From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1481AEB64D8 for ; Thu, 22 Jun 2023 10:55:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230306AbjFVKzE (ORCPT ); Thu, 22 Jun 2023 06:55:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51060 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229840AbjFVKy7 (ORCPT ); Thu, 22 Jun 2023 06:54:59 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DF8031BCD for ; Thu, 22 Jun 2023 03:54:57 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy1q6VQPz9sRm; Thu, 22 Jun 2023 12:54:55 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8vteKcmK8t2W; Thu, 22 Jun 2023 12:54:55 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1q5sm3z9sRF; Thu, 22 Jun 2023 12:54:55 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id C4C7C8B77B; Thu, 22 Jun 2023 12:54:55 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id w-Xb_LZrU174; Thu, 22 Jun 2023 12:54:55 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 742178B763; Thu, 22 Jun 2023 12:54:55 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAsmn82382519 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:48 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAsmqK2382518; Thu, 22 Jun 2023 12:54:48 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 01/14] powerpc/kuap: Avoid unnecessary reads of MD_AP Date: Thu, 22 Jun 2023 12:54:23 +0200 Message-Id: X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431271; l=2619; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=MpFKL0d/EfDJ0kCQxhMEiBWz5R0LOuG+v/7pxC8nbYg=; b=lIpRpaI09XZmhhy+YR7CdWwkYmzpry2LXIIWDSQStUfsyqJjFWQNgq15ypsV29F9ZenjCrkVz pNgnKLa3niWDMazVQ7yuEMIzWnW4uv2xxGR8iDei21rePlRN0EymOCz X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" A disassembly of interrupt_exit_kernel_prepare() shows a useless read of MD_AP register. This is shown by r9 being re-used immediately without doing anything with the value read. c000e0e0: 60 00 00 00 nop c000e0e4: =3D=3D=3D> 7d 3a c2 a6 mfmd_ap r9 <=3D=3D=3D=3D c000e0e8: 7d 20 00 a6 mfmsr r9 c000e0ec: 7c 51 13 a6 mtspr 81,r2 c000e0f0: 81 3f 00 84 lwz r9,132(r31) c000e0f4: 71 29 80 00 andi. r9,r9,32768 kuap_get_and_assert_locked() is paired with kuap_kernel_restore() and are only used in interrupt_exit_kernel_prepare(). The value returned by kuap_get_and_assert_locked() is only used by kuap_kernel_restore(). On 8xx, kuap_kernel_restore() doesn't use the value read by kuap_get_and_assert_locked() so modify kuap_get_and_assert_locked() to not perform the read of MD_AP and return 0 instead. The same applies on BOOKE. Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/nohash/32/kup-8xx.h | 8 ++------ arch/powerpc/include/asm/nohash/kup-booke.h | 6 ++---- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/nohash/32/kup-8xx.h b/arch/powerpc/in= clude/asm/nohash/32/kup-8xx.h index c44d97751723..8579210f2a6a 100644 --- a/arch/powerpc/include/asm/nohash/32/kup-8xx.h +++ b/arch/powerpc/include/asm/nohash/32/kup-8xx.h @@ -41,14 +41,10 @@ static inline void __kuap_kernel_restore(struct pt_regs= *regs, unsigned long kua =20 static inline unsigned long __kuap_get_and_assert_locked(void) { - unsigned long kuap; - - kuap =3D mfspr(SPRN_MD_AP); - if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG)) - WARN_ON_ONCE(kuap >> 16 !=3D MD_APG_KUAP >> 16); + WARN_ON_ONCE(mfspr(SPRN_MD_AP) >> 16 !=3D MD_APG_KUAP >> 16); =20 - return kuap; + return 0; } =20 static inline void __allow_user_access(void __user *to, const void __user = *from, diff --git a/arch/powerpc/include/asm/nohash/kup-booke.h b/arch/powerpc/inc= lude/asm/nohash/kup-booke.h index 49bb41ed0816..823c5a3a96d8 100644 --- a/arch/powerpc/include/asm/nohash/kup-booke.h +++ b/arch/powerpc/include/asm/nohash/kup-booke.h @@ -58,12 +58,10 @@ static inline void __kuap_kernel_restore(struct pt_regs= *regs, unsigned long kua =20 static inline unsigned long __kuap_get_and_assert_locked(void) { - unsigned long kuap =3D mfspr(SPRN_PID); - if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG)) - WARN_ON_ONCE(kuap); + WARN_ON_ONCE(mfspr(SPRN_PID)); =20 - return kuap; + return 0; } =20 static inline void __allow_user_access(void __user *to, const void __user = *from, --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BCE2DEB64D8 for ; Thu, 22 Jun 2023 10:55:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231373AbjFVKzP (ORCPT ); Thu, 22 Jun 2023 06:55:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51074 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230308AbjFVKzH (ORCPT ); Thu, 22 Jun 2023 06:55:07 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2D0051BC5 for ; Thu, 22 Jun 2023 03:55:05 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy1s3TkFz9sRh; Thu, 22 Jun 2023 12:54:57 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VAljZoVwo4TH; Thu, 22 Jun 2023 12:54:57 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1q6KgVz9sRl; Thu, 22 Jun 2023 12:54:55 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id D1EFA8B763; Thu, 22 Jun 2023 12:54:55 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id Z9p6vaLOO-Pf; Thu, 22 Jun 2023 12:54:55 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 77D678B767; Thu, 22 Jun 2023 12:54:55 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAsmib2382524 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:48 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAsmaL2382523; Thu, 22 Jun 2023 12:54:48 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 02/14] powerpc/kuap: Avoid useless jump_label on empty function Date: Thu, 22 Jun 2023 12:54:24 +0200 Message-Id: <49907feaae8275375ce09aa43e739c1aaa89d331.1687430631.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431271; l=8514; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=4zoL5f/NDaOiSGKHw9EM0Ia9dxzFYlOXgNWIOe1S0DA=; b=ZSPVW1vH2nl5dTiEN1zaExDg4JdkEK9xpstSTbwa0LbpzkczjgITOU28lAa81sZWwVA/Y+Kop 8GiWP+CVWVxBbx8ydtdGIIuL1uXHqRXT90mLW4c2Kt6Og2ChVIRiRZk X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Disassembly of interrupt_enter_prepare() shows a pointless nop before the mftb c000abf0 : c000abf0: 81 23 00 84 lwz r9,132(r3) c000abf4: 71 29 40 00 andi. r9,r9,16384 c000abf8: 41 82 00 28 beq- c000ac20 c000abfc: =3D=3D=3D> 60 00 00 00 nop <=3D=3D=3D=3D c000ac00: 7d 0c 42 e6 mftb r8 c000ac04: 80 e2 00 08 lwz r7,8(r2) c000ac08: 81 22 00 28 lwz r9,40(r2) c000ac0c: 91 02 00 24 stw r8,36(r2) c000ac10: 7d 29 38 50 subf r9,r9,r7 c000ac14: 7d 29 42 14 add r9,r9,r8 c000ac18: 91 22 00 08 stw r9,8(r2) c000ac1c: 4e 80 00 20 blr c000ac20: 60 00 00 00 nop c000ac24: 7d 5a c2 a6 mfmd_ap r10 c000ac28: 3d 20 de 00 lis r9,-8704 c000ac2c: 91 43 00 b0 stw r10,176(r3) c000ac30: 7d 3a c3 a6 mtspr 794,r9 c000ac34: 4e 80 00 20 blr That comes from the call to kuap_loc(), allthough __kuap_lock() is an empty function on the 8xx. To avoid that, only perform kuap_is_disabled() check when there is something to do with __kuap_lock(). Do the same with __kuap_save_and_lock() and __kuap_get_and_assert_locked(). Signed-off-by: Christophe Leroy Reviewed-by: Nicholas Piggin --- v2: Add back comment about __kupa_lock() not needed on 64s --- arch/powerpc/include/asm/book3s/32/kup.h | 6 ++--- arch/powerpc/include/asm/book3s/64/kup.h | 10 ++------ arch/powerpc/include/asm/kup.h | 25 ++++++++++---------- arch/powerpc/include/asm/nohash/32/kup-8xx.h | 11 ++++----- arch/powerpc/include/asm/nohash/kup-booke.h | 8 +++++-- 5 files changed, 27 insertions(+), 33 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/32/kup.h b/arch/powerpc/includ= e/asm/book3s/32/kup.h index 678f9c9d89b6..466a19cfb4df 100644 --- a/arch/powerpc/include/asm/book3s/32/kup.h +++ b/arch/powerpc/include/asm/book3s/32/kup.h @@ -77,10 +77,6 @@ static inline void kuap_unlock(unsigned long addr, bool = ool) kuap_unlock_all_ool(); } =20 -static inline void __kuap_lock(void) -{ -} - static inline void __kuap_save_and_lock(struct pt_regs *regs) { unsigned long kuap =3D current->thread.kuap; @@ -92,6 +88,7 @@ static inline void __kuap_save_and_lock(struct pt_regs *r= egs) current->thread.kuap =3D KUAP_NONE; kuap_lock_addr(kuap, false); } +#define __kuap_save_and_lock __kuap_save_and_lock =20 static inline void kuap_user_restore(struct pt_regs *regs) { @@ -120,6 +117,7 @@ static inline unsigned long __kuap_get_and_assert_locke= d(void) =20 return kuap; } +#define __kuap_get_and_assert_locked __kuap_get_and_assert_locked =20 static __always_inline void __allow_user_access(void __user *to, const voi= d __user *from, u32 size, unsigned long dir) diff --git a/arch/powerpc/include/asm/book3s/64/kup.h b/arch/powerpc/includ= e/asm/book3s/64/kup.h index 84c09e546115..2a7bd3ecc556 100644 --- a/arch/powerpc/include/asm/book3s/64/kup.h +++ b/arch/powerpc/include/asm/book3s/64/kup.h @@ -298,15 +298,9 @@ static inline unsigned long __kuap_get_and_assert_lock= ed(void) WARN_ON_ONCE(amr !=3D AMR_KUAP_BLOCKED); return amr; } +#define __kuap_get_and_assert_locked __kuap_get_and_assert_locked =20 -/* Do nothing, book3s/64 does that in ASM */ -static inline void __kuap_lock(void) -{ -} - -static inline void __kuap_save_and_lock(struct pt_regs *regs) -{ -} +/* __kuap_lock() not required, book3s/64 does that in ASM */ =20 /* * We support individually allowing read or write, but we don't support ne= sting diff --git a/arch/powerpc/include/asm/kup.h b/arch/powerpc/include/asm/kup.h index d751ddd08110..0a4e07175612 100644 --- a/arch/powerpc/include/asm/kup.h +++ b/arch/powerpc/include/asm/kup.h @@ -52,16 +52,9 @@ __bad_kuap_fault(struct pt_regs *regs, unsigned long add= ress, bool is_write) return false; } =20 -static inline void __kuap_lock(void) { } -static inline void __kuap_save_and_lock(struct pt_regs *regs) { } static inline void kuap_user_restore(struct pt_regs *regs) { } static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned lo= ng amr) { } =20 -static inline unsigned long __kuap_get_and_assert_locked(void) -{ - return 0; -} - /* * book3s/64/kup-radix.h defines these functions for the !KUAP case to flu= sh * the L1D cache after user accesses. Only include the empty stubs for oth= er @@ -87,27 +80,32 @@ bad_kuap_fault(struct pt_regs *regs, unsigned long addr= ess, bool is_write) =20 static __always_inline void kuap_assert_locked(void) { +#if defined(CONFIG_PPC_KUAP_DEBUG) && defined(__kuap_get_and_assert_locked) if (kuap_is_disabled()) return; =20 - if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG)) - __kuap_get_and_assert_locked(); + __kuap_get_and_assert_locked(); +#endif } =20 static __always_inline void kuap_lock(void) { +#ifdef __kuap_lock if (kuap_is_disabled()) return; =20 __kuap_lock(); +#endif } =20 static __always_inline void kuap_save_and_lock(struct pt_regs *regs) { +#ifdef __kuap_save_and_lock if (kuap_is_disabled()) return; =20 __kuap_save_and_lock(regs); +#endif } =20 static __always_inline void kuap_kernel_restore(struct pt_regs *regs, unsi= gned long amr) @@ -120,10 +118,11 @@ static __always_inline void kuap_kernel_restore(struc= t pt_regs *regs, unsigned l =20 static __always_inline unsigned long kuap_get_and_assert_locked(void) { - if (kuap_is_disabled()) - return 0; - - return __kuap_get_and_assert_locked(); +#ifdef __kuap_get_and_assert_locked + if (!kuap_is_disabled()) + return __kuap_get_and_assert_locked(); +#endif + return 0; } =20 #ifndef CONFIG_PPC_BOOK3S_64 diff --git a/arch/powerpc/include/asm/nohash/32/kup-8xx.h b/arch/powerpc/in= clude/asm/nohash/32/kup-8xx.h index 8579210f2a6a..a372cd822887 100644 --- a/arch/powerpc/include/asm/nohash/32/kup-8xx.h +++ b/arch/powerpc/include/asm/nohash/32/kup-8xx.h @@ -20,15 +20,12 @@ static __always_inline bool kuap_is_disabled(void) return static_branch_unlikely(&disable_kuap_key); } =20 -static inline void __kuap_lock(void) -{ -} - static inline void __kuap_save_and_lock(struct pt_regs *regs) { regs->kuap =3D mfspr(SPRN_MD_AP); mtspr(SPRN_MD_AP, MD_APG_KUAP); } +#define __kuap_save_and_lock __kuap_save_and_lock =20 static inline void kuap_user_restore(struct pt_regs *regs) { @@ -39,13 +36,15 @@ static inline void __kuap_kernel_restore(struct pt_regs= *regs, unsigned long kua mtspr(SPRN_MD_AP, regs->kuap); } =20 +#ifdef CONFIG_PPC_KUAP_DEBUG static inline unsigned long __kuap_get_and_assert_locked(void) { - if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG)) - WARN_ON_ONCE(mfspr(SPRN_MD_AP) >> 16 !=3D MD_APG_KUAP >> 16); + WARN_ON_ONCE(mfspr(SPRN_MD_AP) >> 16 !=3D MD_APG_KUAP >> 16); =20 return 0; } +#define __kuap_get_and_assert_locked __kuap_get_and_assert_locked +#endif =20 static inline void __allow_user_access(void __user *to, const void __user = *from, unsigned long size, unsigned long dir) diff --git a/arch/powerpc/include/asm/nohash/kup-booke.h b/arch/powerpc/inc= lude/asm/nohash/kup-booke.h index 823c5a3a96d8..71182cbe20c3 100644 --- a/arch/powerpc/include/asm/nohash/kup-booke.h +++ b/arch/powerpc/include/asm/nohash/kup-booke.h @@ -30,6 +30,7 @@ static inline void __kuap_lock(void) mtspr(SPRN_PID, 0); isync(); } +#define __kuap_lock __kuap_lock =20 static inline void __kuap_save_and_lock(struct pt_regs *regs) { @@ -37,6 +38,7 @@ static inline void __kuap_save_and_lock(struct pt_regs *r= egs) mtspr(SPRN_PID, 0); isync(); } +#define __kuap_save_and_lock __kuap_save_and_lock =20 static inline void kuap_user_restore(struct pt_regs *regs) { @@ -56,13 +58,15 @@ static inline void __kuap_kernel_restore(struct pt_regs= *regs, unsigned long kua /* Context synchronisation is performed by rfi */ } =20 +#ifdef CONFIG_PPC_KUAP_DEBUG static inline unsigned long __kuap_get_and_assert_locked(void) { - if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG)) - WARN_ON_ONCE(mfspr(SPRN_PID)); + WARN_ON_ONCE(mfspr(SPRN_PID)); =20 return 0; } +#define __kuap_get_and_assert_locked __kuap_get_and_assert_locked +#endif =20 static inline void __allow_user_access(void __user *to, const void __user = *from, unsigned long size, unsigned long dir) --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 704FFEB64D8 for ; Thu, 22 Jun 2023 10:57:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230244AbjFVK5R (ORCPT ); Thu, 22 Jun 2023 06:57:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53220 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230124AbjFVK5M (ORCPT ); Thu, 22 Jun 2023 06:57:12 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 029D41BC5 for ; Thu, 22 Jun 2023 03:56:51 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy25071cz9sRF; Thu, 22 Jun 2023 12:55:09 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mctQSA0J8aYy; Thu, 22 Jun 2023 12:55:08 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1w0Jjvz9sRx; Thu, 22 Jun 2023 12:55:00 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 0539E8B77C; Thu, 22 Jun 2023 12:55:00 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id ECqjHAkRusSo; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 363B68B77B; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAsrME2382563 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:53 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAsr172382527; Thu, 22 Jun 2023 12:54:53 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 03/14] powerpc/kuap: Refactor static branch for disabling kuap Date: Thu, 22 Jun 2023 12:54:25 +0200 Message-Id: X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431271; l=5299; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=AZfoSgZiCwjPgSsKITfozUnMBvKmLZuCyUS8gnNY6TE=; b=HKTcGB8NQMqNSmBnTr0qE530RJYwtRqoVP6TV8kzu8XfcIZqWwjxe6fil+9rpm7nl6gTAgCLf Gx1aGFPMnV/A1omDWGS6tD3xyK7QPaItviXJp2C0GeWusQRz5uT7Xao X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" All but book3s/64 use a static branch key for disabling kuap. book3s/64 uses a memory feature. Refactor all targets except book3s/64. Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/book3s/32/kup.h | 7 ------- arch/powerpc/include/asm/book3s/64/kup.h | 1 + arch/powerpc/include/asm/kup.h | 15 +++++++++++++++ arch/powerpc/include/asm/nohash/32/kup-8xx.h | 7 ------- arch/powerpc/include/asm/nohash/kup-booke.h | 7 ------- arch/powerpc/mm/book3s32/kuap.c | 3 --- arch/powerpc/mm/init-common.c | 3 +++ arch/powerpc/mm/nohash/kup.c | 3 --- 8 files changed, 19 insertions(+), 27 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/32/kup.h b/arch/powerpc/includ= e/asm/book3s/32/kup.h index 466a19cfb4df..8da9997a67ba 100644 --- a/arch/powerpc/include/asm/book3s/32/kup.h +++ b/arch/powerpc/include/asm/book3s/32/kup.h @@ -11,8 +11,6 @@ =20 #include =20 -extern struct static_key_false disable_kuap_key; - static __always_inline bool kuep_is_disabled(void) { return !IS_ENABLED(CONFIG_PPC_KUEP); @@ -25,11 +23,6 @@ static __always_inline bool kuep_is_disabled(void) #define KUAP_NONE (~0UL) #define KUAP_ALL (~1UL) =20 -static __always_inline bool kuap_is_disabled(void) -{ - return static_branch_unlikely(&disable_kuap_key); -} - static inline void kuap_lock_one(unsigned long addr) { mtsr(mfsr(addr) | SR_KS, addr); diff --git a/arch/powerpc/include/asm/book3s/64/kup.h b/arch/powerpc/includ= e/asm/book3s/64/kup.h index 2a7bd3ecc556..d44c4ee2e8c3 100644 --- a/arch/powerpc/include/asm/book3s/64/kup.h +++ b/arch/powerpc/include/asm/book3s/64/kup.h @@ -234,6 +234,7 @@ static __always_inline bool kuap_is_disabled(void) { return !mmu_has_feature(MMU_FTR_BOOK3S_KUAP); } +#define kuap_is_disabled kuap_is_disabled =20 static inline void kuap_user_restore(struct pt_regs *regs) { diff --git a/arch/powerpc/include/asm/kup.h b/arch/powerpc/include/asm/kup.h index 0a4e07175612..74b7f4cee2ed 100644 --- a/arch/powerpc/include/asm/kup.h +++ b/arch/powerpc/include/asm/kup.h @@ -6,6 +6,12 @@ #define KUAP_WRITE 2 #define KUAP_READ_WRITE (KUAP_READ | KUAP_WRITE) =20 +#ifndef __ASSEMBLY__ +#include + +static __always_inline bool kuap_is_disabled(void); +#endif + #ifdef CONFIG_PPC_BOOK3S_64 #include #endif @@ -41,6 +47,15 @@ void setup_kuep(bool disabled); =20 #ifdef CONFIG_PPC_KUAP void setup_kuap(bool disabled); + +#ifndef kuap_is_disabled +extern struct static_key_false disable_kuap_key; + +static __always_inline bool kuap_is_disabled(void) +{ + return static_branch_unlikely(&disable_kuap_key); +} +#endif #else static inline void setup_kuap(bool disabled) { } =20 diff --git a/arch/powerpc/include/asm/nohash/32/kup-8xx.h b/arch/powerpc/in= clude/asm/nohash/32/kup-8xx.h index a372cd822887..1d53f38c5cd5 100644 --- a/arch/powerpc/include/asm/nohash/32/kup-8xx.h +++ b/arch/powerpc/include/asm/nohash/32/kup-8xx.h @@ -13,13 +13,6 @@ =20 #include =20 -extern struct static_key_false disable_kuap_key; - -static __always_inline bool kuap_is_disabled(void) -{ - return static_branch_unlikely(&disable_kuap_key); -} - static inline void __kuap_save_and_lock(struct pt_regs *regs) { regs->kuap =3D mfspr(SPRN_MD_AP); diff --git a/arch/powerpc/include/asm/nohash/kup-booke.h b/arch/powerpc/inc= lude/asm/nohash/kup-booke.h index 71182cbe20c3..07759ae9117b 100644 --- a/arch/powerpc/include/asm/nohash/kup-booke.h +++ b/arch/powerpc/include/asm/nohash/kup-booke.h @@ -18,13 +18,6 @@ =20 #include =20 -extern struct static_key_false disable_kuap_key; - -static __always_inline bool kuap_is_disabled(void) -{ - return static_branch_unlikely(&disable_kuap_key); -} - static inline void __kuap_lock(void) { mtspr(SPRN_PID, 0); diff --git a/arch/powerpc/mm/book3s32/kuap.c b/arch/powerpc/mm/book3s32/kua= p.c index 28676cabb005..c5484729b595 100644 --- a/arch/powerpc/mm/book3s32/kuap.c +++ b/arch/powerpc/mm/book3s32/kuap.c @@ -3,9 +3,6 @@ #include #include =20 -struct static_key_false disable_kuap_key; -EXPORT_SYMBOL(disable_kuap_key); - void kuap_lock_all_ool(void) { kuap_lock_all(); diff --git a/arch/powerpc/mm/init-common.c b/arch/powerpc/mm/init-common.c index 119ef491f797..74e140b1efef 100644 --- a/arch/powerpc/mm/init-common.c +++ b/arch/powerpc/mm/init-common.c @@ -32,6 +32,9 @@ EXPORT_SYMBOL_GPL(kernstart_virt_addr); bool disable_kuep =3D !IS_ENABLED(CONFIG_PPC_KUEP); bool disable_kuap =3D !IS_ENABLED(CONFIG_PPC_KUAP); =20 +struct static_key_false disable_kuap_key; +EXPORT_SYMBOL(disable_kuap_key); + static int __init parse_nosmep(char *p) { if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64)) diff --git a/arch/powerpc/mm/nohash/kup.c b/arch/powerpc/mm/nohash/kup.c index 552becf90e97..4e22adfa2aa8 100644 --- a/arch/powerpc/mm/nohash/kup.c +++ b/arch/powerpc/mm/nohash/kup.c @@ -13,9 +13,6 @@ #include =20 #ifdef CONFIG_PPC_KUAP -struct static_key_false disable_kuap_key; -EXPORT_SYMBOL(disable_kuap_key); - void setup_kuap(bool disabled) { if (disabled) { --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DD906EB64DA for ; Thu, 22 Jun 2023 10:55:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231452AbjFVKzr (ORCPT ); Thu, 22 Jun 2023 06:55:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51684 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231429AbjFVKzf (ORCPT ); Thu, 22 Jun 2023 06:55:35 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D20421BF5 for ; Thu, 22 Jun 2023 03:55:23 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy210013z9sRm; Thu, 22 Jun 2023 12:55:04 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id JzeXHVWfZ6P7; Thu, 22 Jun 2023 12:55:04 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1v70Wsz9sRt; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id EC07F8B763; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id qI5FN3vJJBbQ; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 3B8978B77D; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAsrUl2382567 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:53 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAsrTX2382566; Thu, 22 Jun 2023 12:54:53 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 04/14] powerpc/kuap: Make disabling KUAP at boottime impossible except on book3s/64 Date: Thu, 22 Jun 2023 12:54:26 +0200 Message-Id: <8e178a6823aee38af74dc59d246185bfc4d846d9.1687430631.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431271; l=3711; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=qpT8lcamvy7dK8UQJBZ5uk7RcXiHWOqfTZFEErmAGRw=; b=U9dBB/+u2VxlX8iaDgxnhExM/RgR10aljKoyAeC7MwwAM4kZ9SACfIvBAxTwuSXLsBum47C4N sDEorkMzxQ9BeRp2ptsdZog+OJi/GMkLEY8tvjfOdyAwl5qhcZkfMOb X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" It is possible to disable KUAP at boottime with 'nosmap' parameter. That is implemented with jump_label hence adds a 'nop' in front of each open/close of userspace access. From a security point of view it makes sence to disallow disabling KUAP. And on processors like the 8xx where 'nop' is not seamless, it saves a few cycles. In addition, objtool UACCESS validation cannot cope with that feature because it visits every static branches independentely and is not able to see that when a UACCESS enable is skipped, the matching UACCESS disable is skipped as well. So make KUAP always active when selected in kernel config. In the future it may be re-implemented by noping the instructions instead of using static branches. Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/kup.h | 4 +--- arch/powerpc/mm/book3s32/kuap.c | 15 ++++++--------- arch/powerpc/mm/init-common.c | 6 +++--- arch/powerpc/mm/nohash/kup.c | 8 +------- 4 files changed, 11 insertions(+), 22 deletions(-) diff --git a/arch/powerpc/include/asm/kup.h b/arch/powerpc/include/asm/kup.h index 74b7f4cee2ed..a02340535efa 100644 --- a/arch/powerpc/include/asm/kup.h +++ b/arch/powerpc/include/asm/kup.h @@ -49,11 +49,9 @@ void setup_kuep(bool disabled); void setup_kuap(bool disabled); =20 #ifndef kuap_is_disabled -extern struct static_key_false disable_kuap_key; - static __always_inline bool kuap_is_disabled(void) { - return static_branch_unlikely(&disable_kuap_key); + return false; } #endif #else diff --git a/arch/powerpc/mm/book3s32/kuap.c b/arch/powerpc/mm/book3s32/kua= p.c index c5484729b595..639219d0a821 100644 --- a/arch/powerpc/mm/book3s32/kuap.c +++ b/arch/powerpc/mm/book3s32/kuap.c @@ -17,17 +17,14 @@ EXPORT_SYMBOL(kuap_unlock_all_ool); =20 void setup_kuap(bool disabled) { - if (!disabled) { - kuap_lock_all_ool(); - init_mm.context.sr0 |=3D SR_KS; - current->thread.sr0 |=3D SR_KS; - } + WARN_ON(disabled); + + kuap_lock_all_ool(); + init_mm.context.sr0 |=3D SR_KS; + current->thread.sr0 |=3D SR_KS; =20 if (smp_processor_id() !=3D boot_cpuid) return; =20 - if (disabled) - static_branch_enable(&disable_kuap_key); - else - pr_info("Activating Kernel Userspace Access Protection\n"); + pr_info("Activating Kernel Userspace Access Protection\n"); } diff --git a/arch/powerpc/mm/init-common.c b/arch/powerpc/mm/init-common.c index 74e140b1efef..237086742ec7 100644 --- a/arch/powerpc/mm/init-common.c +++ b/arch/powerpc/mm/init-common.c @@ -32,9 +32,6 @@ EXPORT_SYMBOL_GPL(kernstart_virt_addr); bool disable_kuep =3D !IS_ENABLED(CONFIG_PPC_KUEP); bool disable_kuap =3D !IS_ENABLED(CONFIG_PPC_KUAP); =20 -struct static_key_false disable_kuap_key; -EXPORT_SYMBOL(disable_kuap_key); - static int __init parse_nosmep(char *p) { if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64)) @@ -48,6 +45,9 @@ early_param("nosmep", parse_nosmep); =20 static int __init parse_nosmap(char *p) { + if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64)) + return 0; + disable_kuap =3D true; pr_warn("Disabling Kernel Userspace Access Protection\n"); return 0; diff --git a/arch/powerpc/mm/nohash/kup.c b/arch/powerpc/mm/nohash/kup.c index 4e22adfa2aa8..3bb79f89de06 100644 --- a/arch/powerpc/mm/nohash/kup.c +++ b/arch/powerpc/mm/nohash/kup.c @@ -15,13 +15,7 @@ #ifdef CONFIG_PPC_KUAP void setup_kuap(bool disabled) { - if (disabled) { - if (IS_ENABLED(CONFIG_40x)) - disable_kuep =3D true; - if (smp_processor_id() =3D=3D boot_cpuid) - static_branch_enable(&disable_kuap_key); - return; - } + WARN_ON(disabled); =20 pr_info("Activating Kernel Userspace Access Protection\n"); =20 --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3EE49EB64D8 for ; Thu, 22 Jun 2023 10:56:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230270AbjFVK4R (ORCPT ); Thu, 22 Jun 2023 06:56:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52252 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229542AbjFVK4M (ORCPT ); Thu, 22 Jun 2023 06:56:12 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A8CD269A for ; Thu, 22 Jun 2023 03:55:44 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy220kTmz9sRt; Thu, 22 Jun 2023 12:55:06 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DN_Yv-bwXxxU; Thu, 22 Jun 2023 12:55:06 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1w0FY4z9sRv; Thu, 22 Jun 2023 12:55:00 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id F40508B763; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id UbFMWNmsP-iN; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 2F7838B768; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAssSf2382571 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:54 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAsshO2382570; Thu, 22 Jun 2023 12:54:54 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 05/14] powerpc/kuap: KUAP enabling/disabling functions must be __always_inline Date: Thu, 22 Jun 2023 12:54:27 +0200 Message-Id: <651a79379902dcdfbbed30244d7d555b90c4c999.1687430631.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431271; l=17774; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=L8r3xBgXNsl4reNYL5RzipUL/enzeMqtOSUA4t0bcgs=; b=iaGBWfWfIxzPVfI7Td3KCjhnPR2USY3mZBt6PdgpzhKZTaIzo5iAu9llOvPN12DTqS6xHqOA/ k397FJNHazLA1nUN4MA3AsU+oDop9/ePiZtd/xWjcClK5mXuvAGDZyk X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Objtool reports following warnings: arch/powerpc/kernel/signal_32.o: warning: objtool: __prevent_user_access.constprop.0+0x4 (.text+0x4): redundant UACCESS disable arch/powerpc/kernel/signal_32.o: warning: objtool: user_access_begin+0x2c (.text+0x4c): return with UACCESS enabled arch/powerpc/kernel/signal_32.o: warning: objtool: handle_rt_signal32+0x1= 88 (.text+0x360): call to __prevent_user_access.constprop.0() with UACCESS= enabled arch/powerpc/kernel/signal_32.o: warning: objtool: handle_signal32+0x150 (.text+0x4d4): call to __prevent_user_access.constprop.0() with UACCESS= enabled This is due to some KUAP enabling/disabling functions being outline allthough they are marked inline. Use __always_inline instead. Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/book3s/32/kup.h | 26 ++++++++++---------- arch/powerpc/include/asm/book3s/64/kup.h | 23 ++++++++--------- arch/powerpc/include/asm/kup.h | 16 ++++++------ arch/powerpc/include/asm/nohash/32/kup-8xx.h | 20 +++++++-------- arch/powerpc/include/asm/nohash/kup-booke.h | 22 ++++++++--------- arch/powerpc/include/asm/uaccess.h | 6 ++--- 6 files changed, 57 insertions(+), 56 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/32/kup.h b/arch/powerpc/includ= e/asm/book3s/32/kup.h index 8da9997a67ba..41746a22c650 100644 --- a/arch/powerpc/include/asm/book3s/32/kup.h +++ b/arch/powerpc/include/asm/book3s/32/kup.h @@ -23,25 +23,25 @@ static __always_inline bool kuep_is_disabled(void) #define KUAP_NONE (~0UL) #define KUAP_ALL (~1UL) =20 -static inline void kuap_lock_one(unsigned long addr) +static __always_inline void kuap_lock_one(unsigned long addr) { mtsr(mfsr(addr) | SR_KS, addr); isync(); /* Context sync required after mtsr() */ } =20 -static inline void kuap_unlock_one(unsigned long addr) +static __always_inline void kuap_unlock_one(unsigned long addr) { mtsr(mfsr(addr) & ~SR_KS, addr); isync(); /* Context sync required after mtsr() */ } =20 -static inline void kuap_lock_all(void) +static __always_inline void kuap_lock_all(void) { update_user_segments(mfsr(0) | SR_KS); isync(); /* Context sync required after mtsr() */ } =20 -static inline void kuap_unlock_all(void) +static __always_inline void kuap_unlock_all(void) { update_user_segments(mfsr(0) & ~SR_KS); isync(); /* Context sync required after mtsr() */ @@ -50,7 +50,7 @@ static inline void kuap_unlock_all(void) void kuap_lock_all_ool(void); void kuap_unlock_all_ool(void); =20 -static inline void kuap_lock_addr(unsigned long addr, bool ool) +static __always_inline void kuap_lock_addr(unsigned long addr, bool ool) { if (likely(addr !=3D KUAP_ALL)) kuap_lock_one(addr); @@ -60,7 +60,7 @@ static inline void kuap_lock_addr(unsigned long addr, boo= l ool) kuap_lock_all_ool(); } =20 -static inline void kuap_unlock(unsigned long addr, bool ool) +static __always_inline void kuap_unlock(unsigned long addr, bool ool) { if (likely(addr !=3D KUAP_ALL)) kuap_unlock_one(addr); @@ -70,7 +70,7 @@ static inline void kuap_unlock(unsigned long addr, bool o= ol) kuap_unlock_all_ool(); } =20 -static inline void __kuap_save_and_lock(struct pt_regs *regs) +static __always_inline void __kuap_save_and_lock(struct pt_regs *regs) { unsigned long kuap =3D current->thread.kuap; =20 @@ -83,11 +83,11 @@ static inline void __kuap_save_and_lock(struct pt_regs = *regs) } #define __kuap_save_and_lock __kuap_save_and_lock =20 -static inline void kuap_user_restore(struct pt_regs *regs) +static __always_inline void kuap_user_restore(struct pt_regs *regs) { } =20 -static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned lo= ng kuap) +static __always_inline void __kuap_kernel_restore(struct pt_regs *regs, un= signed long kuap) { if (unlikely(kuap !=3D KUAP_NONE)) { current->thread.kuap =3D KUAP_NONE; @@ -102,7 +102,7 @@ static inline void __kuap_kernel_restore(struct pt_regs= *regs, unsigned long kua kuap_unlock(regs->kuap, false); } =20 -static inline unsigned long __kuap_get_and_assert_locked(void) +static __always_inline unsigned long __kuap_get_and_assert_locked(void) { unsigned long kuap =3D current->thread.kuap; =20 @@ -137,7 +137,7 @@ static __always_inline void __prevent_user_access(unsig= ned long dir) kuap_lock_addr(kuap, true); } =20 -static inline unsigned long __prevent_user_access_return(void) +static __always_inline unsigned long __prevent_user_access_return(void) { unsigned long flags =3D current->thread.kuap; =20 @@ -149,7 +149,7 @@ static inline unsigned long __prevent_user_access_retur= n(void) return flags; } =20 -static inline void __restore_user_access(unsigned long flags) +static __always_inline void __restore_user_access(unsigned long flags) { if (flags !=3D KUAP_NONE) { current->thread.kuap =3D flags; @@ -157,7 +157,7 @@ static inline void __restore_user_access(unsigned long = flags) } } =20 -static inline bool +static __always_inline bool __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_writ= e) { unsigned long kuap =3D regs->kuap; diff --git a/arch/powerpc/include/asm/book3s/64/kup.h b/arch/powerpc/includ= e/asm/book3s/64/kup.h index d44c4ee2e8c3..f33e064b9f5f 100644 --- a/arch/powerpc/include/asm/book3s/64/kup.h +++ b/arch/powerpc/include/asm/book3s/64/kup.h @@ -213,14 +213,14 @@ extern u64 __ro_after_init default_iamr; * access restrictions. Because of this ignore AMR value when accessing * userspace via kernel thread. */ -static inline u64 current_thread_amr(void) +static __always_inline u64 current_thread_amr(void) { if (current->thread.regs) return current->thread.regs->amr; return default_amr; } =20 -static inline u64 current_thread_iamr(void) +static __always_inline u64 current_thread_iamr(void) { if (current->thread.regs) return current->thread.regs->iamr; @@ -236,7 +236,7 @@ static __always_inline bool kuap_is_disabled(void) } #define kuap_is_disabled kuap_is_disabled =20 -static inline void kuap_user_restore(struct pt_regs *regs) +static __always_inline void kuap_user_restore(struct pt_regs *regs) { bool restore_amr =3D false, restore_iamr =3D false; unsigned long amr, iamr; @@ -275,7 +275,7 @@ static inline void kuap_user_restore(struct pt_regs *re= gs) */ } =20 -static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned lo= ng amr) +static __always_inline void __kuap_kernel_restore(struct pt_regs *regs, un= signed long amr) { if (likely(regs->amr =3D=3D amr)) return; @@ -291,7 +291,7 @@ static inline void __kuap_kernel_restore(struct pt_regs= *regs, unsigned long amr */ } =20 -static inline unsigned long __kuap_get_and_assert_locked(void) +static __always_inline unsigned long __kuap_get_and_assert_locked(void) { unsigned long amr =3D mfspr(SPRN_AMR); =20 @@ -308,7 +308,7 @@ static inline unsigned long __kuap_get_and_assert_locke= d(void) * because that would require an expensive read/modify write of the AMR. */ =20 -static inline unsigned long get_kuap(void) +static __always_inline unsigned long get_kuap(void) { /* * We return AMR_KUAP_BLOCKED when we don't support KUAP because @@ -338,7 +338,8 @@ static __always_inline void set_kuap(unsigned long valu= e) isync(); } =20 -static inline bool __bad_kuap_fault(struct pt_regs *regs, unsigned long ad= dress, bool is_write) +static __always_inline bool +__bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_writ= e) { /* * For radix this will be a storage protection fault (DSISR_PROTFAULT). @@ -381,12 +382,12 @@ static __always_inline void allow_user_access(void __= user *to, const void __user =20 #else /* CONFIG_PPC_KUAP */ =20 -static inline unsigned long get_kuap(void) +static __always_inline unsigned long get_kuap(void) { return AMR_KUAP_BLOCKED; } =20 -static inline void set_kuap(unsigned long value) { } +static __always_inline void set_kuap(unsigned long value) { } =20 static __always_inline void allow_user_access(void __user *to, const void = __user *from, unsigned long size, unsigned long dir) @@ -401,7 +402,7 @@ static __always_inline void prevent_user_access(unsigne= d long dir) do_uaccess_flush(); } =20 -static inline unsigned long prevent_user_access_return(void) +static __always_inline unsigned long prevent_user_access_return(void) { unsigned long flags =3D get_kuap(); =20 @@ -412,7 +413,7 @@ static inline unsigned long prevent_user_access_return(= void) return flags; } =20 -static inline void restore_user_access(unsigned long flags) +static __always_inline void restore_user_access(unsigned long flags) { set_kuap(flags); if (static_branch_unlikely(&uaccess_flush_key) && flags =3D=3D AMR_KUAP_B= LOCKED) diff --git a/arch/powerpc/include/asm/kup.h b/arch/powerpc/include/asm/kup.h index a02340535efa..132f1c7e1064 100644 --- a/arch/powerpc/include/asm/kup.h +++ b/arch/powerpc/include/asm/kup.h @@ -59,14 +59,14 @@ static inline void setup_kuap(bool disabled) { } =20 static __always_inline bool kuap_is_disabled(void) { return true; } =20 -static inline bool +static __always_inline bool __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_writ= e) { return false; } =20 -static inline void kuap_user_restore(struct pt_regs *regs) { } -static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned lo= ng amr) { } +static __always_inline void kuap_user_restore(struct pt_regs *regs) { } +static __always_inline void __kuap_kernel_restore(struct pt_regs *regs, un= signed long amr) { } =20 /* * book3s/64/kup-radix.h defines these functions for the !KUAP case to flu= sh @@ -74,11 +74,11 @@ static inline void __kuap_kernel_restore(struct pt_regs= *regs, unsigned long amr * platforms. */ #ifndef CONFIG_PPC_BOOK3S_64 -static inline void __allow_user_access(void __user *to, const void __user = *from, - unsigned long size, unsigned long dir) { } -static inline void __prevent_user_access(unsigned long dir) { } -static inline unsigned long __prevent_user_access_return(void) { return 0U= L; } -static inline void __restore_user_access(unsigned long flags) { } +static __always_inline void __allow_user_access(void __user *to, const voi= d __user *from, + unsigned long size, unsigned long dir) { } +static __always_inline void __prevent_user_access(unsigned long dir) { } +static __always_inline unsigned long __prevent_user_access_return(void) { = return 0UL; } +static __always_inline void __restore_user_access(unsigned long flags) { } #endif /* CONFIG_PPC_BOOK3S_64 */ #endif /* CONFIG_PPC_KUAP */ =20 diff --git a/arch/powerpc/include/asm/nohash/32/kup-8xx.h b/arch/powerpc/in= clude/asm/nohash/32/kup-8xx.h index 1d53f38c5cd5..61067e4c8f22 100644 --- a/arch/powerpc/include/asm/nohash/32/kup-8xx.h +++ b/arch/powerpc/include/asm/nohash/32/kup-8xx.h @@ -13,24 +13,24 @@ =20 #include =20 -static inline void __kuap_save_and_lock(struct pt_regs *regs) +static __always_inline void __kuap_save_and_lock(struct pt_regs *regs) { regs->kuap =3D mfspr(SPRN_MD_AP); mtspr(SPRN_MD_AP, MD_APG_KUAP); } #define __kuap_save_and_lock __kuap_save_and_lock =20 -static inline void kuap_user_restore(struct pt_regs *regs) +static __always_inline void kuap_user_restore(struct pt_regs *regs) { } =20 -static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned lo= ng kuap) +static __always_inline void __kuap_kernel_restore(struct pt_regs *regs, un= signed long kuap) { mtspr(SPRN_MD_AP, regs->kuap); } =20 #ifdef CONFIG_PPC_KUAP_DEBUG -static inline unsigned long __kuap_get_and_assert_locked(void) +static __always_inline unsigned long __kuap_get_and_assert_locked(void) { WARN_ON_ONCE(mfspr(SPRN_MD_AP) >> 16 !=3D MD_APG_KUAP >> 16); =20 @@ -39,18 +39,18 @@ static inline unsigned long __kuap_get_and_assert_locke= d(void) #define __kuap_get_and_assert_locked __kuap_get_and_assert_locked #endif =20 -static inline void __allow_user_access(void __user *to, const void __user = *from, - unsigned long size, unsigned long dir) +static __always_inline void __allow_user_access(void __user *to, const voi= d __user *from, + unsigned long size, unsigned long dir) { mtspr(SPRN_MD_AP, MD_APG_INIT); } =20 -static inline void __prevent_user_access(unsigned long dir) +static __always_inline void __prevent_user_access(unsigned long dir) { mtspr(SPRN_MD_AP, MD_APG_KUAP); } =20 -static inline unsigned long __prevent_user_access_return(void) +static __always_inline unsigned long __prevent_user_access_return(void) { unsigned long flags; =20 @@ -61,12 +61,12 @@ static inline unsigned long __prevent_user_access_retur= n(void) return flags; } =20 -static inline void __restore_user_access(unsigned long flags) +static __always_inline void __restore_user_access(unsigned long flags) { mtspr(SPRN_MD_AP, flags); } =20 -static inline bool +static __always_inline bool __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_writ= e) { return !((regs->kuap ^ MD_APG_KUAP) & 0xff000000); diff --git a/arch/powerpc/include/asm/nohash/kup-booke.h b/arch/powerpc/inc= lude/asm/nohash/kup-booke.h index 07759ae9117b..416f3e0897d5 100644 --- a/arch/powerpc/include/asm/nohash/kup-booke.h +++ b/arch/powerpc/include/asm/nohash/kup-booke.h @@ -18,14 +18,14 @@ =20 #include =20 -static inline void __kuap_lock(void) +static __always_inline void __kuap_lock(void) { mtspr(SPRN_PID, 0); isync(); } #define __kuap_lock __kuap_lock =20 -static inline void __kuap_save_and_lock(struct pt_regs *regs) +static __always_inline void __kuap_save_and_lock(struct pt_regs *regs) { regs->kuap =3D mfspr(SPRN_PID); mtspr(SPRN_PID, 0); @@ -33,7 +33,7 @@ static inline void __kuap_save_and_lock(struct pt_regs *r= egs) } #define __kuap_save_and_lock __kuap_save_and_lock =20 -static inline void kuap_user_restore(struct pt_regs *regs) +static __always_inline void kuap_user_restore(struct pt_regs *regs) { if (kuap_is_disabled()) return; @@ -43,7 +43,7 @@ static inline void kuap_user_restore(struct pt_regs *regs) /* Context synchronisation is performed by rfi */ } =20 -static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned lo= ng kuap) +static __always_inline void __kuap_kernel_restore(struct pt_regs *regs, un= signed long kuap) { if (regs->kuap) mtspr(SPRN_PID, current->thread.pid); @@ -52,7 +52,7 @@ static inline void __kuap_kernel_restore(struct pt_regs *= regs, unsigned long kua } =20 #ifdef CONFIG_PPC_KUAP_DEBUG -static inline unsigned long __kuap_get_and_assert_locked(void) +static __always_inline unsigned long __kuap_get_and_assert_locked(void) { WARN_ON_ONCE(mfspr(SPRN_PID)); =20 @@ -61,20 +61,20 @@ static inline unsigned long __kuap_get_and_assert_locke= d(void) #define __kuap_get_and_assert_locked __kuap_get_and_assert_locked #endif =20 -static inline void __allow_user_access(void __user *to, const void __user = *from, - unsigned long size, unsigned long dir) +static __always_inline void __allow_user_access(void __user *to, const voi= d __user *from, + unsigned long size, unsigned long dir) { mtspr(SPRN_PID, current->thread.pid); isync(); } =20 -static inline void __prevent_user_access(unsigned long dir) +static __always_inline void __prevent_user_access(unsigned long dir) { mtspr(SPRN_PID, 0); isync(); } =20 -static inline unsigned long __prevent_user_access_return(void) +static __always_inline unsigned long __prevent_user_access_return(void) { unsigned long flags =3D mfspr(SPRN_PID); =20 @@ -84,7 +84,7 @@ static inline unsigned long __prevent_user_access_return(= void) return flags; } =20 -static inline void __restore_user_access(unsigned long flags) +static __always_inline void __restore_user_access(unsigned long flags) { if (flags) { mtspr(SPRN_PID, current->thread.pid); @@ -92,7 +92,7 @@ static inline void __restore_user_access(unsigned long fl= ags) } } =20 -static inline bool +static __always_inline bool __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_writ= e) { return !regs->kuap; diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/= uaccess.h index a2d255aa9627..fb725ec77926 100644 --- a/arch/powerpc/include/asm/uaccess.h +++ b/arch/powerpc/include/asm/uaccess.h @@ -386,7 +386,7 @@ copy_mc_to_user(void __user *to, const void *from, unsi= gned long n) extern long __copy_from_user_flushcache(void *dst, const void __user *src, unsigned size); =20 -static __must_check inline bool user_access_begin(const void __user *ptr, = size_t len) +static __must_check __always_inline bool user_access_begin(const void __us= er *ptr, size_t len) { if (unlikely(!access_ok(ptr, len))) return false; @@ -401,7 +401,7 @@ static __must_check inline bool user_access_begin(const= void __user *ptr, size_t #define user_access_save prevent_user_access_return #define user_access_restore restore_user_access =20 -static __must_check inline bool +static __must_check __always_inline bool user_read_access_begin(const void __user *ptr, size_t len) { if (unlikely(!access_ok(ptr, len))) @@ -415,7 +415,7 @@ user_read_access_begin(const void __user *ptr, size_t l= en) #define user_read_access_begin user_read_access_begin #define user_read_access_end prevent_current_read_from_user =20 -static __must_check inline bool +static __must_check __always_inline bool user_write_access_begin(const void __user *ptr, size_t len) { if (unlikely(!access_ok(ptr, len))) --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89CB5EB64D8 for ; Thu, 22 Jun 2023 10:55:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231300AbjFVKz0 (ORCPT ); Thu, 22 Jun 2023 06:55:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51142 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230510AbjFVKzS (ORCPT ); Thu, 22 Jun 2023 06:55:18 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC64F1BD3 for ; Thu, 22 Jun 2023 03:55:13 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy1y1tjlz9sRl; Thu, 22 Jun 2023 12:55:02 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8Z_ayM7DivRu; Thu, 22 Jun 2023 12:55:02 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1v5Ms0z9sRn; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id B4BDF8B763; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id ycc1lKp4m78l; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 2E0CF8B767; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAss182382575 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:54 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAssQm2382574; Thu, 22 Jun 2023 12:54:54 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 06/14] Revert "powerpc/bug: Provide better flexibility to WARN_ON/__WARN_FLAGS() with asm goto" Date: Thu, 22 Jun 2023 12:54:28 +0200 Message-Id: <3d9a833f451e27c24fe705d6ab845979590be73e.1687430631.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431271; l=6894; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=3RW612N+R2QBIWLhCpp0GHyd7UuL3xMbkiHybzjsti0=; b=Q1k0TnkhFxsJspb3TJppu1qlix3KqPI/U898qpNW6SpPfkYI3E+m7FJG8ojioo129mjtHiJpR +KgFqEIQze+AJgKARehsZZ9dMnhWPRG+EXau6oRGXDicN5zWCK6Sy1Y X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This reverts commit 1e688dd2a3d6759d416616ff07afc4bb836c4213. That commit aimed at optimising the code around generation of WARN_ON/BUG_ON but this leads to a lot of dead code erroneously generated by GCC. That dead code becomes a problem when we start using objtool validation because objtool will abort validation with a warning as soon as it detects unreachable code. This is because unreachable code might be the indication that objtool doesn't properly decode object text. text data bss dec hex filename 9551585 3627834 224376 13403795 cc8693 vmlinux.before 9535281 3628358 224376 13388015 cc48ef vmlinux.after Once this change is reverted, in a standard configuration (pmac32 + function tracer) the text is reduced by 16k which is around 1.7% Taking into account that other problems are encountered with that 'asm goto' in WARN_ON(), including build failures, keeping that change is not worth it allthough it is primarily a compiler bug. So revert it for now. Signed-off-by: Christophe Leroy Acked-by: Naveen N Rao --- v2: Do not remove tools/testing/selftests/powerpc/primitives/asm/extable.h = and leave EX_TABLE in asm/extable.h --- arch/powerpc/include/asm/book3s/64/kup.h | 2 +- arch/powerpc/include/asm/bug.h | 67 ++++-------------------- arch/powerpc/kernel/misc_32.S | 2 +- arch/powerpc/kernel/traps.c | 9 +--- 4 files changed, 15 insertions(+), 65 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/kup.h b/arch/powerpc/includ= e/asm/book3s/64/kup.h index f33e064b9f5f..7c8cc0f096b1 100644 --- a/arch/powerpc/include/asm/book3s/64/kup.h +++ b/arch/powerpc/include/asm/book3s/64/kup.h @@ -90,7 +90,7 @@ /* Prevent access to userspace using any key values */ LOAD_REG_IMMEDIATE(\gpr2, AMR_KUAP_BLOCKED) 999: tdne \gpr1, \gpr2 - EMIT_WARN_ENTRY 999b, __FILE__, __LINE__, (BUGFLAG_WARNING | BUGFLAG_ONCE) + EMIT_BUG_ENTRY 999b, __FILE__, __LINE__, (BUGFLAG_WARNING | BUGFLAG_ONCE) END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_BOOK3S_KUAP, 67) #endif .endm diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index ef42adb44aa3..a565995fb742 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h @@ -4,14 +4,13 @@ #ifdef __KERNEL__ =20 #include -#include =20 #ifdef CONFIG_BUG =20 #ifdef __ASSEMBLY__ #include #ifdef CONFIG_DEBUG_BUGVERBOSE -.macro __EMIT_BUG_ENTRY addr,file,line,flags +.macro EMIT_BUG_ENTRY addr,file,line,flags .section __bug_table,"aw" 5001: .4byte \addr - . .4byte 5002f - . @@ -23,7 +22,7 @@ .previous .endm #else -.macro __EMIT_BUG_ENTRY addr,file,line,flags +.macro EMIT_BUG_ENTRY addr,file,line,flags .section __bug_table,"aw" 5001: .4byte \addr - . .short \flags @@ -32,18 +31,6 @@ .endm #endif /* verbose */ =20 -.macro EMIT_WARN_ENTRY addr,file,line,flags - EX_TABLE(\addr,\addr+4) - __EMIT_BUG_ENTRY \addr,\file,\line,\flags -.endm - -.macro EMIT_BUG_ENTRY addr,file,line,flags - .if \flags & 1 /* BUGFLAG_WARNING */ - .err /* Use EMIT_WARN_ENTRY for warnings */ - .endif - __EMIT_BUG_ENTRY \addr,\file,\line,\flags -.endm - #else /* !__ASSEMBLY__ */ /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and sizeof(struct bug_entry), respectively */ @@ -73,16 +60,6 @@ "i" (sizeof(struct bug_entry)), \ ##__VA_ARGS__) =20 -#define WARN_ENTRY(insn, flags, label, ...) \ - asm_volatile_goto( \ - "1: " insn "\n" \ - EX_TABLE(1b, %l[label]) \ - _EMIT_BUG_ENTRY \ - : : "i" (__FILE__), "i" (__LINE__), \ - "i" (flags), \ - "i" (sizeof(struct bug_entry)), \ - ##__VA_ARGS__ : : label) - /* * BUG_ON() and WARN_ON() do their best to cooperate with compile-time * optimisations. However depending on the complexity of the condition @@ -95,16 +72,7 @@ } while (0) #define HAVE_ARCH_BUG =20 -#define __WARN_FLAGS(flags) do { \ - __label__ __label_warn_on; \ - \ - WARN_ENTRY("twi 31, 0, 0", BUGFLAG_WARNING | (flags), __label_warn_on); \ - barrier_before_unreachable(); \ - __builtin_unreachable(); \ - \ -__label_warn_on: \ - break; \ -} while (0) +#define __WARN_FLAGS(flags) BUG_ENTRY("twi 31, 0, 0", BUGFLAG_WARNING | (f= lags)) =20 #ifdef CONFIG_PPC64 #define BUG_ON(x) do { \ @@ -117,25 +85,15 @@ __label_warn_on: \ } while (0) =20 #define WARN_ON(x) ({ \ - bool __ret_warn_on =3D false; \ - do { \ - if (__builtin_constant_p((x))) { \ - if (!(x)) \ - break; \ + int __ret_warn_on =3D !!(x); \ + if (__builtin_constant_p(__ret_warn_on)) { \ + if (__ret_warn_on) \ __WARN(); \ - __ret_warn_on =3D true; \ - } else { \ - __label__ __label_warn_on; \ - \ - WARN_ENTRY(PPC_TLNEI " %4, 0", \ - BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN), \ - __label_warn_on, \ - "r" ((__force long)(x))); \ - break; \ -__label_warn_on: \ - __ret_warn_on =3D true; \ - } \ - } while (0); \ + } else { \ + BUG_ENTRY(PPC_TLNEI " %4, 0", \ + BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN), \ + "r" (__ret_warn_on)); \ + } \ unlikely(__ret_warn_on); \ }) =20 @@ -148,11 +106,8 @@ __label_warn_on: \ #ifdef __ASSEMBLY__ .macro EMIT_BUG_ENTRY addr,file,line,flags .endm -.macro EMIT_WARN_ENTRY addr,file,line,flags -.endm #else /* !__ASSEMBLY__ */ #define _EMIT_BUG_ENTRY -#define _EMIT_WARN_ENTRY #endif #endif /* CONFIG_BUG */ =20 diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index daf8f87d2372..fd11ec42df89 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -237,7 +237,7 @@ _GLOBAL(copy_page) addi r3,r3,-4 =20 0: twnei r5, 0 /* WARN if r3 is not cache aligned */ - EMIT_WARN_ENTRY 0b,__FILE__,__LINE__, BUGFLAG_WARNING + EMIT_BUG_ENTRY 0b,__FILE__,__LINE__, BUGFLAG_WARNING =20 addi r4,r4,-4 =20 diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index e59ec6d32d37..7ef147e2a20d 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1508,13 +1508,8 @@ static void do_program_check(struct pt_regs *regs) =20 if (!(regs->msr & MSR_PR) && /* not user-mode */ report_bug(bugaddr, regs) =3D=3D BUG_TRAP_TYPE_WARN) { - const struct exception_table_entry *entry; - - entry =3D search_exception_tables(bugaddr); - if (entry) { - regs_set_return_ip(regs, extable_fixup(entry) + regs->nip - bugaddr); - return; - } + regs_add_return_ip(regs, 4); + return; } =20 if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) && user_mode(regs)) { --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8545EB64DC for ; Thu, 22 Jun 2023 10:55:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231451AbjFVKzV (ORCPT ); Thu, 22 Jun 2023 06:55:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230504AbjFVKzL (ORCPT ); Thu, 22 Jun 2023 06:55:11 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 99FB41BD0 for ; Thu, 22 Jun 2023 03:55:10 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy1x1hLcz9sRq; Thu, 22 Jun 2023 12:55:01 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wrVW5_Sg7hsw; Thu, 22 Jun 2023 12:55:01 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1v41MDz9sRl; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 85B4C8B781; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id IkVAEYjgjW-B; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 2BA4A8B763; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAssDW2382579 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:54 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAssoA2382578; Thu, 22 Jun 2023 12:54:54 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 07/14] objtool: Allow an architecture to disable objtool on ASM files Date: Thu, 22 Jun 2023 12:54:29 +0200 Message-Id: <247d738f8907045b1910cd6aff8efbb08ed57a84.1687430631.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431272; l=1429; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=JMHcrTE+ZNL5DPWKb6wzfxgfrGY7fEc11+Jar29nty8=; b=R3PKeOmYJP5Q0fBoGRwqMrbCkL8MN/BqJY4+G0JXtTemJkL/PFK0Rr9pGqjThgaeU6hG0TesY 5l8KYAzNgdUATEnjFeU6fTFGS5QaBU2OrZJ9rbBSYjY/c7bk9BkIYGp X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Supporting objtool on ASM files requires quite an effort. Features like UACCESS validation don't require ASM files validation. In order to allow architectures to enable objtool validation without spending unnecessary effort on cleaning up ASM files, provide an option to disable objtool validation on ASM files. Suggested-by: Naveen N Rao Signed-off-by: Christophe Leroy --- arch/Kconfig | 5 +++++ scripts/Makefile.build | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index 205fd23e0cad..dd66b884bcfb 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1091,6 +1091,11 @@ config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT config HAVE_OBJTOOL bool =20 +config ARCH_OBJTOOL_SKIP_ASM + bool + help + Architecture doesn't support objtool on ASM files + config HAVE_JUMP_LABEL_HACK bool =20 diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 9f94fc83f086..878027cf4faf 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -359,7 +359,11 @@ $(obj)/%.s: $(src)/%.S FORCE $(call if_changed_dep,cpp_s_S) =20 quiet_cmd_as_o_S =3D AS $(quiet_modtag) $@ +ifndef CONFIG_ARCH_OBJTOOL_SKIP_ASM cmd_as_o_S =3D $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool) +else + cmd_as_o_S =3D $(CC) $(a_flags) -c -o $@ $< +endif =20 ifdef CONFIG_ASM_MODVERSIONS =20 --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8007CEB64DA for ; Thu, 22 Jun 2023 10:55:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230433AbjFVKzh (ORCPT ); Thu, 22 Jun 2023 06:55:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231440AbjFVKzV (ORCPT ); Thu, 22 Jun 2023 06:55:21 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C56D1FC1 for ; Thu, 22 Jun 2023 03:55:18 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy1z2rnNz9sRn; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id V2sTXnLGuWS1; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1v6Sspz9sRs; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id DA12C8B763; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id Xnxzm3g9CkGg; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 3732F8B77C; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAssr72382583 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:54 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAssQM2382582; Thu, 22 Jun 2023 12:54:54 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 08/14] objtool: Fix JUMP_ENTRY_SIZE for bi-arch like powerpc Date: Thu, 22 Jun 2023 12:54:30 +0200 Message-Id: <85a0e5fde0c36219332a74871ef4699008ec7edb.1687430631.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431272; l=2995; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=oDQ+yu2c80GlkN1xTGQWllMn8lTFly+buQPlZ9vYv6s=; b=6vfsq3Ai6s9XeMQ1kxtJ6r3TF2kx85UhChrMJNVC4mdQ8sLprQlge6yFmcRWx40NJePTmHT3I XfRCVc4YhaAB1BLREE9Z8hKbzZY5Mz6XVdJI3m/cPrUXr8TtPxzAFbs X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" struct jump_entry { s32 code; s32 target; long key; }; It means that the size of the third argument depends on whether we are building a 32 bits or 64 bits kernel. Therefore JUMP_ENTRY_SIZE must depend on elf_class_addrsize(elf). To allow that, entries[] table must be initialised at runtime. This is easily done by moving it into its only user which is special_get_alts(). Signed-off-by: Christophe Leroy Acked-by: Peter Zijlstra (Intel) --- .../arch/powerpc/include/arch/special.h | 2 +- tools/objtool/special.c | 55 +++++++++---------- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/tools/objtool/arch/powerpc/include/arch/special.h b/tools/objt= ool/arch/powerpc/include/arch/special.h index ffef9ada7133..ede05633c2e4 100644 --- a/tools/objtool/arch/powerpc/include/arch/special.h +++ b/tools/objtool/arch/powerpc/include/arch/special.h @@ -6,7 +6,7 @@ #define EX_ORIG_OFFSET 0 #define EX_NEW_OFFSET 4 =20 -#define JUMP_ENTRY_SIZE 16 +#define JUMP_ENTRY_SIZE (8 + elf_class_addrsize(elf)) /* 12 on PPC32, 16 o= n PPC64 */ #define JUMP_ORIG_OFFSET 0 #define JUMP_NEW_OFFSET 4 #define JUMP_KEY_OFFSET 8 diff --git a/tools/objtool/special.c b/tools/objtool/special.c index baa85c31526b..4015c1cd0fe1 100644 --- a/tools/objtool/special.c +++ b/tools/objtool/special.c @@ -26,34 +26,6 @@ struct special_entry { unsigned char key; /* jump_label key */ }; =20 -static const struct special_entry entries[] =3D { - { - .sec =3D ".altinstructions", - .group =3D true, - .size =3D ALT_ENTRY_SIZE, - .orig =3D ALT_ORIG_OFFSET, - .orig_len =3D ALT_ORIG_LEN_OFFSET, - .new =3D ALT_NEW_OFFSET, - .new_len =3D ALT_NEW_LEN_OFFSET, - .feature =3D ALT_FEATURE_OFFSET, - }, - { - .sec =3D "__jump_table", - .jump_or_nop =3D true, - .size =3D JUMP_ENTRY_SIZE, - .orig =3D JUMP_ORIG_OFFSET, - .new =3D JUMP_NEW_OFFSET, - .key =3D JUMP_KEY_OFFSET, - }, - { - .sec =3D "__ex_table", - .size =3D EX_ENTRY_SIZE, - .orig =3D EX_ORIG_OFFSET, - .new =3D EX_NEW_OFFSET, - }, - {}, -}; - void __weak arch_handle_alternative(unsigned short feature, struct special= _alt *alt) { } @@ -144,6 +116,33 @@ int special_get_alts(struct elf *elf, struct list_head= *alts) unsigned int nr_entries; struct special_alt *alt; int idx, ret; + const struct special_entry entries[] =3D { + { + .sec =3D ".altinstructions", + .group =3D true, + .size =3D ALT_ENTRY_SIZE, + .orig =3D ALT_ORIG_OFFSET, + .orig_len =3D ALT_ORIG_LEN_OFFSET, + .new =3D ALT_NEW_OFFSET, + .new_len =3D ALT_NEW_LEN_OFFSET, + .feature =3D ALT_FEATURE_OFFSET, + }, + { + .sec =3D "__jump_table", + .jump_or_nop =3D true, + .size =3D JUMP_ENTRY_SIZE, + .orig =3D JUMP_ORIG_OFFSET, + .new =3D JUMP_NEW_OFFSET, + .key =3D JUMP_KEY_OFFSET, + }, + { + .sec =3D "__ex_table", + .size =3D EX_ENTRY_SIZE, + .orig =3D EX_ORIG_OFFSET, + .new =3D EX_NEW_OFFSET, + }, + {}, + }; =20 INIT_LIST_HEAD(alts); =20 --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96329EB64D8 for ; Thu, 22 Jun 2023 10:56:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230063AbjFVK4y (ORCPT ); Thu, 22 Jun 2023 06:56:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229958AbjFVK4t (ORCPT ); Thu, 22 Jun 2023 06:56:49 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 47E1B1FC0 for ; Thu, 22 Jun 2023 03:56:25 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy232Hvsz9sRv; Thu, 22 Jun 2023 12:55:07 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id y9BuGBbWDjEh; Thu, 22 Jun 2023 12:55:07 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1w0GYXz9sRw; Thu, 22 Jun 2023 12:55:00 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 0322C8B767; Thu, 22 Jun 2023 12:55:00 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id dNi4r_wckg9f; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 3DFF58B77E; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAssLm2382587 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:54 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAss1E2382586; Thu, 22 Jun 2023 12:54:54 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 09/14] objtool: Add INSN_RETURN_CONDITIONAL Date: Thu, 22 Jun 2023 12:54:31 +0200 Message-Id: X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431272; l=3334; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=9SrAYCC2bWhKsjar9FgexzpLtlQEyIgc8lTK6+czby0=; b=/ENMFNCKcocOYmHbGQRIGtZobNaHc3llvVDbdWQYOwMoe8XxVEJaLzuxXr29ZZXxkcN+Y99aw pLeLU+O82PuDsoLjXpODiJI9dq7pvb/NClQ/Y2BHVE9nb1T0SI0R2WB X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Most functions have an unconditional return at the end, like this one: 00000000 : 0: 81 22 04 d0 lwz r9,1232(r2) 4: 38 60 00 00 li r3,0 8: 2c 09 00 00 cmpwi r9,0 c: 4d 82 00 20 beqlr <=3D=3D Conditional return 10: 80 69 00 a0 lwz r3,160(r9) 14: 54 63 00 36 clrrwi r3,r3,4 18: 68 63 04 00 xori r3,r3,1024 1c: 7c 63 00 34 cntlzw r3,r3 20: 54 63 d9 7e srwi r3,r3,5 24: 4e 80 00 20 blr <=3D=3D Unconditional return But other functions like this other one below only have conditional returns: 00000028 : 28: 81 25 00 00 lwz r9,0(r5) 2c: 2c 08 00 00 cmpwi r8,0 30: 7d 29 30 78 andc r9,r9,r6 34: 7d 27 3b 78 or r7,r9,r7 38: 54 84 65 3a rlwinm r4,r4,12,20,29 3c: 81 23 00 18 lwz r9,24(r3) 40: 41 82 00 58 beq 98 44: 7d 29 20 2e lwzx r9,r9,r4 48: 55 29 07 3a rlwinm r9,r9,0,28,29 4c: 2c 09 00 0c cmpwi r9,12 50: 41 82 00 08 beq 58 54: 39 00 00 80 li r8,128 58: 2c 08 00 01 cmpwi r8,1 5c: 90 e5 00 00 stw r7,0(r5) 60: 4d a2 00 20 beqlr+ <=3D=3D Conditional return 64: 7c e9 3b 78 mr r9,r7 68: 39 40 00 00 li r10,0 6c: 39 4a 00 04 addi r10,r10,4 70: 7c 0a 40 00 cmpw r10,r8 74: 91 25 00 04 stw r9,4(r5) 78: 91 25 00 08 stw r9,8(r5) 7c: 38 a5 00 10 addi r5,r5,16 80: 91 25 ff fc stw r9,-4(r5) 84: 4c 80 00 20 bgelr <=3D=3D Conditional return 88: 55 49 60 26 slwi r9,r10,12 8c: 7d 29 3a 14 add r9,r9,r7 90: 91 25 00 00 stw r9,0(r5) 94: 4b ff ff d8 b 6c 98: 39 00 00 04 li r8,4 9c: 4b ff ff bc b 58 If conditional returns are decoded as INSN_OTHER, objtool considers that the second function never returns. If conditional returns are decoded as INSN_RETURN, objtool considers that code after that conditional return is dead. To overcome this situation, introduce INSN_RETURN_CONDITIONAL which is taken as a confirmation that a function is not noreturn but still sees following code as reachable. Signed-off-by: Christophe Leroy Acked-by: Peter Zijlstra (Intel) --- tools/objtool/check.c | 2 +- tools/objtool/include/objtool/arch.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 0fcf99c91400..8977cdf93f54 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -259,7 +259,7 @@ static bool __dead_end_function(struct objtool_file *fi= le, struct symbol *func, func_for_each_insn(file, func, insn) { empty =3D false; =20 - if (insn->type =3D=3D INSN_RETURN) + if (insn->type =3D=3D INSN_RETURN || insn->type =3D=3D INSN_RETURN_CONDI= TIONAL) return false; } =20 diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/o= bjtool/arch.h index 2b6d2ce4f9a5..84ba75112934 100644 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -19,6 +19,7 @@ enum insn_type { INSN_CALL, INSN_CALL_DYNAMIC, INSN_RETURN, + INSN_RETURN_CONDITIONAL, INSN_CONTEXT_SWITCH, INSN_BUG, INSN_NOP, --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 270F7EB64DA for ; Thu, 22 Jun 2023 10:57:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230373AbjFVK5b (ORCPT ); Thu, 22 Jun 2023 06:57:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53502 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229958AbjFVK52 (ORCPT ); Thu, 22 Jun 2023 06:57:28 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0FE281BF6 for ; Thu, 22 Jun 2023 03:57:14 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy261sJdz9sRw; Thu, 22 Jun 2023 12:55:10 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7h7cRNzj8o8D; Thu, 22 Jun 2023 12:55:10 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1w0LvVz9sRy; Thu, 22 Jun 2023 12:55:00 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 07B5A8B77D; Thu, 22 Jun 2023 12:55:00 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id B_gfYa5CvPIE; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 3EE278B780; Thu, 22 Jun 2023 12:54:59 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAssbH2382591 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:54 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAss3e2382590; Thu, 22 Jun 2023 12:54:54 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 10/14] objtool: Add support for relative switch tables Date: Thu, 22 Jun 2023 12:54:32 +0200 Message-Id: <1d60e0ffe692289fd01485f680e87161bef98760.1687430631.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431272; l=6797; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=xvlcGloqvQ2Rre7Q94wG8EUJ6xZSV+MbLLnxuvwPGC4=; b=JvulI/ygHvEYPWgk+Ik3QDika4dOXY5JE8/Z/jhRMM3MKVb7/G+ZutHXu0bLEiREAerpojtB5 22TajAU2KGgCp+peNeYcOzfWpeIHUbbQk52wLxlcipeBIQ9RtRwee2l X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" On powerpc, switch tables are relative, than means the address of the table is added to the value of the entry in order to get the pointed address: (r10 is the table address, r4 the index in the table) lis r10,0 <=3D=3D Load r10 with upper part of .rodata address R_PPC_ADDR16_HA .rodata addi r10,r10,0 <=3D=3D Add lower part of .rodata address R_PPC_ADDR16_LO .rodata lwzx r8,r10,r4 <=3D=3D Read table entry at r10 + r4 into r8 add r10,r8,r10 <=3D=3D Add table address to read value mtctr r10 <=3D=3D Save calculated address in CTR bctr <=3D=3D Branch to address in CTR But for c_jump_tables it is not the case, they contain the pointed address directly: lis r28,0 <=3D=3D Load r28 with upper .rodata..c_jump_table R_PPC_ADDR16_HA .rodata..c_jump_table addi r28,r28,0 <=3D=3D Add lower part of .rodata..c_jump_table R_PPC_ADDR16_LO .rodata..c_jump_table lwzx r10,r28,r10 <=3D=3D Read table entry at r10 + r28 into r10 mtctr r10 <=3D=3D Save read value in CTR bctr <=3D=3D Branch to address in CTR Add support to objtool for relative tables, with a flag in order to tell table by table if that table uses relative or absolute addressing. And use correct size for 'long' instead of hard coding a size of '8'. Signed-off-by: Christophe Leroy --- tools/objtool/arch/powerpc/special.c | 2 +- tools/objtool/arch/x86/special.c | 3 ++- tools/objtool/check.c | 21 ++++++++++++++------- tools/objtool/include/objtool/elf.h | 1 + tools/objtool/include/objtool/special.h | 2 +- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/tools/objtool/arch/powerpc/special.c b/tools/objtool/arch/powe= rpc/special.c index d33868147196..979b555b16ea 100644 --- a/tools/objtool/arch/powerpc/special.c +++ b/tools/objtool/arch/powerpc/special.c @@ -13,7 +13,7 @@ bool arch_support_alt_relocation(struct special_alt *spec= ial_alt, } =20 struct reloc *arch_find_switch_table(struct objtool_file *file, - struct instruction *insn) + struct instruction *insn, bool *is_rel) { exit(-1); } diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/spec= ial.c index 7c97b7391279..e7e1775f313a 100644 --- a/tools/objtool/arch/x86/special.c +++ b/tools/objtool/arch/x86/special.c @@ -92,7 +92,7 @@ bool arch_support_alt_relocation(struct special_alt *spec= ial_alt, * NOTE: RETPOLINE made it harder still to decode dynamic jumps. */ struct reloc *arch_find_switch_table(struct objtool_file *file, - struct instruction *insn) + struct instruction *insn, bool *is_rel) { struct reloc *text_reloc, *rodata_reloc; struct section *table_sec; @@ -141,5 +141,6 @@ struct reloc *arch_find_switch_table(struct objtool_fil= e *file, if (text_reloc->type =3D=3D R_X86_64_PC32) file->ignore_unreachables =3D true; =20 + *is_rel =3D false; return rodata_reloc; } diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 8977cdf93f54..b810be087d7c 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2053,7 +2053,7 @@ static int add_jump_table(struct objtool_file *file, = struct instruction *insn, struct instruction *dest_insn; struct alternative *alt; struct symbol *pfunc =3D insn_func(insn)->pfunc; - unsigned int prev_offset =3D 0; + unsigned int offset, prev_offset =3D 0; =20 /* * Each @reloc is a switch table relocation which points to the target @@ -2066,7 +2066,7 @@ static int add_jump_table(struct objtool_file *file, = struct instruction *insn, break; =20 /* Make sure the table entries are consecutive: */ - if (prev_offset && reloc->offset !=3D prev_offset + 8) + if (prev_offset && reloc->offset !=3D prev_offset + elf_class_addrsize(f= ile->elf)) break; =20 /* Detect function pointers from contiguous objects: */ @@ -2074,7 +2074,12 @@ static int add_jump_table(struct objtool_file *file,= struct instruction *insn, reloc->addend =3D=3D pfunc->offset) break; =20 - dest_insn =3D find_insn(file, reloc->sym->sec, reloc->addend); + if (table->jump_table_is_rel) + offset =3D reloc->addend + table->offset - reloc->offset; + else + offset =3D reloc->addend; + + dest_insn =3D find_insn(file, reloc->sym->sec, offset); if (!dest_insn) break; =20 @@ -2107,8 +2112,8 @@ static int add_jump_table(struct objtool_file *file, = struct instruction *insn, * associated with it. */ static struct reloc *find_jump_table(struct objtool_file *file, - struct symbol *func, - struct instruction *insn) + struct symbol *func, + struct instruction *insn, bool *is_rel) { struct reloc *table_reloc; struct instruction *dest_insn, *orig_insn =3D insn; @@ -2132,7 +2137,7 @@ static struct reloc *find_jump_table(struct objtool_f= ile *file, insn->jump_dest->offset > orig_insn->offset)) break; =20 - table_reloc =3D arch_find_switch_table(file, insn); + table_reloc =3D arch_find_switch_table(file, insn, is_rel); if (!table_reloc) continue; dest_insn =3D find_insn(file, table_reloc->sym->sec, table_reloc->addend= ); @@ -2154,6 +2159,7 @@ static void mark_func_jump_tables(struct objtool_file= *file, { struct instruction *insn, *last =3D NULL; struct reloc *reloc; + bool is_rel; =20 func_for_each_insn(file, func, insn) { if (!last) @@ -2176,9 +2182,10 @@ static void mark_func_jump_tables(struct objtool_fil= e *file, if (insn->type !=3D INSN_JUMP_DYNAMIC) continue; =20 - reloc =3D find_jump_table(file, func, insn); + reloc =3D find_jump_table(file, func, insn, &is_rel); if (reloc) { reloc->jump_table_start =3D true; + reloc->jump_table_is_rel =3D is_rel; insn->_jump_table =3D reloc; } } diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index e1ca588eb69d..64aac87a4825 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -80,6 +80,7 @@ struct reloc { s64 addend; int idx; bool jump_table_start; + bool jump_table_is_rel; }; =20 #define ELF_HASH_BITS 20 diff --git a/tools/objtool/include/objtool/special.h b/tools/objtool/includ= e/objtool/special.h index 86d4af9c5aa9..5edfc4c3e582 100644 --- a/tools/objtool/include/objtool/special.h +++ b/tools/objtool/include/objtool/special.h @@ -38,5 +38,5 @@ bool arch_support_alt_relocation(struct special_alt *spec= ial_alt, struct instruction *insn, struct reloc *reloc); struct reloc *arch_find_switch_table(struct objtool_file *file, - struct instruction *insn); + struct instruction *insn, bool *is_rel); #endif /* _SPECIAL_H */ --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D544EEB64D8 for ; Thu, 22 Jun 2023 10:57:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229958AbjFVK5t (ORCPT ); Thu, 22 Jun 2023 06:57:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53788 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229691AbjFVK5o (ORCPT ); Thu, 22 Jun 2023 06:57:44 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B44771BD0 for ; Thu, 22 Jun 2023 03:57:30 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy2744Lcz9sRx; Thu, 22 Jun 2023 12:55:11 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id TwCvSKTJ9sVX; Thu, 22 Jun 2023 12:55:11 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1z3mW7z9sRs; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 7CA6C8B77C; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id 6PNygAm5LxyL; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 0F4D08B767; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAstUv2382595 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:55 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAstMN2382594; Thu, 22 Jun 2023 12:54:55 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 11/14] objtool: Remove too strict constraint in jump table search Date: Thu, 22 Jun 2023 12:54:33 +0200 Message-Id: <4ffd1d04d761033fb4d37d99f6371aa7ce385fce.1687430631.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431272; l=1238; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=xo5GsLhzhIPQQtob5FKg1ykAv6UQtqGkIwMUerLF3lM=; b=qahKpueot6MkAktB7/xwC9riFe4nHh330iLqM9czKtaQ58pRInWcHOqTERsJhQ3X8OLKCYY2P r2BSF5HnVZSBFeMXkse6J4AnvH+XCHAPLALgqMmdfdHzxJOmNv5TPiQ X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In code there is often a pattern like: load jump table address do some test conditional jump to label1: do something unconditional jump to label2: label1: do something else read jump table dynamic jump label2: do other job here .... find_jump_table() contains a constraint that stops the backsearch of the table address loading when a jump is found in-between. Remove that constraint. Signed-off-by: Christophe Leroy --- tools/objtool/check.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index b810be087d7c..1911de0e1008 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2130,13 +2130,6 @@ static struct reloc *find_jump_table(struct objtool_= file *file, if (insn !=3D orig_insn && insn->type =3D=3D INSN_JUMP_DYNAMIC) break; =20 - /* allow small jumps within the range */ - if (insn->type =3D=3D INSN_JUMP_UNCONDITIONAL && - insn->jump_dest && - (insn->jump_dest->offset <=3D insn->offset || - insn->jump_dest->offset > orig_insn->offset)) - break; - table_reloc =3D arch_find_switch_table(file, insn, is_rel); if (!table_reloc) continue; --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C93AEB64D8 for ; Thu, 22 Jun 2023 10:58:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231160AbjFVK6K (ORCPT ); Thu, 22 Jun 2023 06:58:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230510AbjFVK6A (ORCPT ); Thu, 22 Jun 2023 06:58:00 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E6B71BF9 for ; Thu, 22 Jun 2023 03:57:46 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy282g5Tz9sRh; Thu, 22 Jun 2023 12:55:12 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id GDkNPYkUjt_7; Thu, 22 Jun 2023 12:55:12 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1z42ffz9sS1; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 845B98B767; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id jCWcX67Wjy5O; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 11C5A8B768; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAstNa2382599 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:55 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAstSh2382598; Thu, 22 Jun 2023 12:54:55 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 12/14] objtool: Add support for more complex UACCESS control Date: Thu, 22 Jun 2023 12:54:34 +0200 Message-Id: <02c7ecdfe636f078027fc110ab73b90331d9eb70.1687430631.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431272; l=3698; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=fjC9fclDEUFOtttguru3wB33LM6pcFc4vZHnzw2Vn0U=; b=IM3RM+Rrro0UsYaCEkR4VeLAIVl+Wq5oUAqu7PTWJzGt9FFTg1lNWpXizQjH6Du4yDBXBq30H K33QrbF4XW6CRrGF5BMzcII2Ugn12oixcC+eQMS/eWl3vVNMlEuOKN8 X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" On x86, UACCESS is controlled by two instructions: STAC and CLAC. STAC instruction enables UACCESS while CLAC disables UACCESS. This is simple enough for objtool to locate UACCESS enable and disable. But on powerpc it is a bit more complex, the same instruction is used for enabling and disabling UACCESS, and the same instruction can be used for many other things. It would be too complex to use exclusively instruction decoding. To help objtool, mark such instruction into .discard.uaccess_begin and .discard.uaccess_end sections, on the same principle as for reachable/unreachable instructions. And add ASM_UACCESS_BEGIN and ASM_UACCESS_END macros to be used in inline assembly code to annotate UACCESS enable and UACCESS disable instructions. Signed-off-by: Christophe Leroy --- include/linux/objtool.h | 14 +++++++++++++ tools/objtool/check.c | 44 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/include/linux/objtool.h b/include/linux/objtool.h index 03f82c2c2ebf..d8fde4158a40 100644 --- a/include/linux/objtool.h +++ b/include/linux/objtool.h @@ -57,6 +57,18 @@ ".long 998b - .\n\t" \ ".popsection\n\t" =20 +#define ASM_UACCESS_BEGIN \ + "998:\n\t" \ + ".pushsection .discard.uaccess_begin\n\t" \ + ".long 998b - .\n\t" \ + ".popsection\n\t" + +#define ASM_UACCESS_END \ + "998:\n\t" \ + ".pushsection .discard.uaccess_end\n\t" \ + ".long 998b - .\n\t" \ + ".popsection\n\t" + #else /* __ASSEMBLY__ */ =20 /* @@ -156,6 +168,8 @@ #define STACK_FRAME_NON_STANDARD_FP(func) #define ANNOTATE_NOENDBR #define ASM_REACHABLE +#define ASM_UACCESS_BEGIN +#define ASM_UACCESS_END #else #define ANNOTATE_INTRA_FUNCTION_CALL .macro UNWIND_HINT type:req sp_reg=3D0 sp_offset=3D0 signal=3D0 diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 1911de0e1008..f850ab892ad5 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1110,6 +1110,49 @@ static void add_ignores(struct objtool_file *file) } } =20 +static void add_uaccess(struct objtool_file *file) +{ + struct section *sec; + struct reloc *reloc; + struct instruction *insn; + + sec =3D find_section_by_name(file->elf, ".rela.discard.uaccess_begin"); + if (!sec) + return; + + list_for_each_entry(reloc, &sec->reloc_list, list) { + if (reloc->sym->type !=3D STT_SECTION) { + WARN("unexpected relocation symbol type in %s", sec->name); + continue; + } + insn =3D find_insn(file, reloc->sym->sec, reloc->addend); + if (!insn) { + WARN("can't find UACCESS enable insn at %s+0x%" PRIx64, + reloc->sym->sec->name, reloc->addend); + continue; + } + insn->type =3D INSN_STAC; + } + + sec =3D find_section_by_name(file->elf, ".rela.discard.uaccess_end"); + if (!sec) + return; + + list_for_each_entry(reloc, &sec->reloc_list, list) { + if (reloc->sym->type !=3D STT_SECTION) { + WARN("unexpected relocation symbol type in %s", sec->name); + continue; + } + insn =3D find_insn(file, reloc->sym->sec, reloc->addend); + if (!insn) { + WARN("can't find UACCESS disable insn at %s+0x%" PRIx64, + reloc->sym->sec->name, reloc->addend); + continue; + } + insn->type =3D INSN_CLAC; + } +} + /* * This is a whitelist of functions that is allowed to be called with AC s= et. * The list is meant to be minimal and only contains compiler instrumentat= ion @@ -2608,6 +2651,7 @@ static int decode_sections(struct objtool_file *file) return ret; =20 add_ignores(file); + add_uaccess(file); add_uaccess_safe(file); =20 ret =3D add_ignore_alternatives(file); --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3FD60EB64D8 for ; Thu, 22 Jun 2023 10:58:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231398AbjFVK6e (ORCPT ); Thu, 22 Jun 2023 06:58:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54696 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231428AbjFVK6W (ORCPT ); Thu, 22 Jun 2023 06:58:22 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E207D1FF2 for ; Thu, 22 Jun 2023 03:58:16 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy2B19JFz9sRy; Thu, 22 Jun 2023 12:55:14 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1i7GCOvs_3fi; Thu, 22 Jun 2023 12:55:14 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1z466Dz9sS2; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 886E78B77D; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id Qx6bjsuqdINP; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 1349F8B77B; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAst7U2382603 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:55 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAstrf2382602; Thu, 22 Jun 2023 12:54:55 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 13/14] powerpc/bug: Annotate reachable after warning trap Date: Thu, 22 Jun 2023 12:54:35 +0200 Message-Id: X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431272; l=2316; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=/W4+xqj0r7zNXbQJn/jQRk2PTNbpBc+Jr6goIjqzvwg=; b=TD/95uGV7fn5nikSzDwHKl57kO2RzzOio+Nwz/LkTCP1Fxdc8R+C0cbguVoXQ5QbZiUb8zuGX zheE5iP1J/VDgT5KzUTfR68jop11OJpuAMK+g2h8TRdQTRpfDK+OwLA X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This commit is copied from commit bfb1a7c91fb7 ("x86/bug: Merge annotate_reachable() into _BUG_FLAGS() asm") 'twi 31,0,0' is a BUG instruction, which is by default a dead end. But the same instruction is used for WARNINGs and the execution resumes with the following instruction. Mark it reachable so that objtool knows that it is not a dead end in that case. Also change the unreachable() annotation by __builtin_unreachable() since objtool already knows that a BUG instruction is a dead end. Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/bug.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index a565995fb742..5550ebffb146 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h @@ -4,6 +4,7 @@ #ifdef __KERNEL__ =20 #include +#include =20 #ifdef CONFIG_BUG =20 @@ -51,10 +52,11 @@ ".previous\n" #endif =20 -#define BUG_ENTRY(insn, flags, ...) \ +#define BUG_ENTRY(insn, flags, extra, ...) \ __asm__ __volatile__( \ "1: " insn "\n" \ _EMIT_BUG_ENTRY \ + extra \ : : "i" (__FILE__), "i" (__LINE__), \ "i" (flags), \ "i" (sizeof(struct bug_entry)), \ @@ -67,12 +69,12 @@ */ =20 #define BUG() do { \ - BUG_ENTRY("twi 31, 0, 0", 0); \ - unreachable(); \ + BUG_ENTRY("twi 31, 0, 0", 0, ""); \ + __builtin_unreachable(); \ } while (0) #define HAVE_ARCH_BUG =20 -#define __WARN_FLAGS(flags) BUG_ENTRY("twi 31, 0, 0", BUGFLAG_WARNING | (f= lags)) +#define __WARN_FLAGS(flags) BUG_ENTRY("twi 31, 0, 0", BUGFLAG_WARNING | (f= lags), ASM_REACHABLE) =20 #ifdef CONFIG_PPC64 #define BUG_ON(x) do { \ @@ -80,7 +82,7 @@ if (x) \ BUG(); \ } else { \ - BUG_ENTRY(PPC_TLNEI " %4, 0", 0, "r" ((__force long)(x))); \ + BUG_ENTRY(PPC_TLNEI " %4, 0", 0, "", "r" ((__force long)(x))); \ } \ } while (0) =20 @@ -92,7 +94,7 @@ } else { \ BUG_ENTRY(PPC_TLNEI " %4, 0", \ BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN), \ - "r" (__ret_warn_on)); \ + "", "r" (__ret_warn_on)); \ } \ unlikely(__ret_warn_on); \ }) --=20 2.40.1 From nobody Sat Feb 7 22:01:48 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5CB72EB64D8 for ; Thu, 22 Jun 2023 10:58:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231331AbjFVK6X (ORCPT ); Thu, 22 Jun 2023 06:58:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54388 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229590AbjFVK6O (ORCPT ); Thu, 22 Jun 2023 06:58:14 -0400 Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3E95B2105 for ; Thu, 22 Jun 2023 03:58:03 -0700 (PDT) Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Qmy293Bmpz9sRs; Thu, 22 Jun 2023 12:55:13 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0y8zvkea4ST8; Thu, 22 Jun 2023 12:55:13 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Qmy1z42L8z9sS0; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 85FA68B77C; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id ZAHRRKp1hzW3; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (unknown [192.168.232.14]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 0F4DF8B763; Thu, 22 Jun 2023 12:55:03 +0200 (CEST) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 35MAstH22382608 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 22 Jun 2023 12:54:55 +0200 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 35MAstt92382607; Thu, 22 Jun 2023 12:54:55 +0200 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Michael Ellerman , Nicholas Piggin , Josh Poimboeuf , Peter Zijlstra , Sathvika Vasireddy , Naveen N Rao Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 14/14] powerpc: Implement UACCESS validation on PPC32 Date: Thu, 22 Jun 2023 12:54:36 +0200 Message-Id: X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1687431272; l=13818; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=gGCZPMWcuDAJxDyLtoC/Wa9LU9DPZyUBcIAjsrrKoPY=; b=QkK2Cs1jjnRQKTzTCHOcUNHUkm4s6aDFRKDhP8tOH/rsWl73Ooqpyv2M4yf4CGAjeePgFRXbl GBuOQGO7jHZA/IZgD5pk2VfMWk7seVHjuPLs5vnVm11xS4f9gByLjpx X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In order to implement UACCESS validation, objtool support for powerpc needs to be enhanced to decode more instructions. It also requires implementation of switch tables finding. On PPC32 it is similar to x86, switch tables are anonymous in .rodata, the difference is that the value is relative to its index in the table. Then comes the UACCESS enabling/disabling instructions. On booke and 8xx it is done with a mtspr instruction. For 8xx that's in SPRN_MD_AP, for booke that's in SPRN_PID. Annotate those instructions. For book3s/32 that's a bit more complex and left aside for the moment. No work has been done for ASM files, they are not used for UACCESS so for the moment just tell objtool to ignore ASM files. For relocable code, the .got2 relocation preceding each global function needs to be marked as ignored because some versions of GCC do this: 120: R_PPC_REL32 .got2+0x7ff0 00000124 : 124: 94 21 ff f0 stwu r1,-16(r1) 128: 7c 08 02 a6 mflr r0 12c: 42 9f 00 05 bcl 20,4*cr7+so,130 130: 39 00 00 00 li r8,0 134: 39 20 00 08 li r9,8 138: 93 c1 00 08 stw r30,8(r1) 13c: 7f c8 02 a6 mflr r30 140: 90 01 00 14 stw r0,20(r1) 144: 80 1e ff f0 lwz r0,-16(r30) 148: 7f c0 f2 14 add r30,r0,r30 14c: 81 5e 80 00 lwz r10,-32768(r30) 150: 80 fe 80 04 lwz r7,-32764(r30) While other versions do that: 00000120 : 120: 94 21 ff f0 stwu r1,-16(r1) 124: 7c 08 02 a6 mflr r0 128: 42 9f 00 05 bcl 20,4*cr7+so,12c 12c: 39 00 00 00 li r8,0 130: 39 20 00 08 li r9,8 134: 93 c1 00 08 stw r30,8(r1) 138: 7f c8 02 a6 mflr r30 13c: 3f de 00 00 addis r30,r30,0 13e: R_PPC_REL16_HA .got2+0x8012 140: 90 01 00 14 stw r0,20(r1) 144: 3b de 00 00 addi r30,r30,0 146: R_PPC_REL16_LO .got2+0x801a 148: 81 5e 80 00 lwz r10,-32768(r30) 14c: 80 fe 80 04 lwz r7,-32764(r30) Also declare longjmp() and start_secondary_resume() as global noreturn functions, and declare __copy_tofrom_user() and __arch_clear_user() as UACCESS safe. Signed-off-by: Christophe Leroy --- arch/powerpc/Kconfig | 2 + arch/powerpc/include/asm/kup.h | 12 +++ arch/powerpc/include/asm/nohash/32/kup-8xx.h | 8 +- arch/powerpc/include/asm/nohash/kup-booke.h | 8 +- arch/powerpc/kexec/core_32.c | 4 +- tools/objtool/arch/powerpc/decode.c | 82 ++++++++++++++++++-- tools/objtool/arch/powerpc/special.c | 42 +++++++++- tools/objtool/check.c | 5 ++ 8 files changed, 148 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 8b955bc7b59f..8b613e520143 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -160,6 +160,7 @@ config PPC select ARCH_KEEP_MEMBLOCK select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO + select ARCH_OBJTOOL_SKIP_ASM select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT select ARCH_SPLIT_ARG64 if PPC32 @@ -258,6 +259,7 @@ config PPC select HAVE_OPTPROBES select HAVE_OBJTOOL if PPC32 || MPROFILE_KERNEL select HAVE_OBJTOOL_MCOUNT if HAVE_OBJTOOL + select HAVE_UACCESS_VALIDATION if HAVE_OBJTOOL && PPC_KUAP && PPC32 select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS_NMI if PPC64 select HAVE_PERF_REGS diff --git a/arch/powerpc/include/asm/kup.h b/arch/powerpc/include/asm/kup.h index 132f1c7e1064..9f824cb93d8a 100644 --- a/arch/powerpc/include/asm/kup.h +++ b/arch/powerpc/include/asm/kup.h @@ -10,6 +10,8 @@ #include =20 static __always_inline bool kuap_is_disabled(void); +static __always_inline void mtspr_uaccess_begin(int rn, unsigned long val); +static __always_inline void mtspr_uaccess_end(int rn, unsigned long val); #endif =20 #ifdef CONFIG_PPC_BOOK3S_64 @@ -222,6 +224,16 @@ static __always_inline void prevent_current_write_to_u= ser(void) prevent_user_access(KUAP_WRITE); } =20 +static __always_inline void mtspr_uaccess_begin(int rn, unsigned long val) +{ + asm(ASM_UACCESS_BEGIN "mtspr %0, %1\n\t" : : "i"(rn), "r"(val) : "memory"= ); +} + +static __always_inline void mtspr_uaccess_end(int rn, unsigned long val) +{ + asm(ASM_UACCESS_END "mtspr %0, %1\n\t" : : "i"(rn), "r"(val) : "memory"); +} + #endif /* !__ASSEMBLY__ */ =20 #endif /* _ASM_POWERPC_KUAP_H_ */ diff --git a/arch/powerpc/include/asm/nohash/32/kup-8xx.h b/arch/powerpc/in= clude/asm/nohash/32/kup-8xx.h index 61067e4c8f22..9b59231d87c9 100644 --- a/arch/powerpc/include/asm/nohash/32/kup-8xx.h +++ b/arch/powerpc/include/asm/nohash/32/kup-8xx.h @@ -42,12 +42,12 @@ static __always_inline unsigned long __kuap_get_and_ass= ert_locked(void) static __always_inline void __allow_user_access(void __user *to, const voi= d __user *from, unsigned long size, unsigned long dir) { - mtspr(SPRN_MD_AP, MD_APG_INIT); + mtspr_uaccess_begin(SPRN_MD_AP, MD_APG_INIT); } =20 static __always_inline void __prevent_user_access(unsigned long dir) { - mtspr(SPRN_MD_AP, MD_APG_KUAP); + mtspr_uaccess_end(SPRN_MD_AP, MD_APG_KUAP); } =20 static __always_inline unsigned long __prevent_user_access_return(void) @@ -56,14 +56,14 @@ static __always_inline unsigned long __prevent_user_acc= ess_return(void) =20 flags =3D mfspr(SPRN_MD_AP); =20 - mtspr(SPRN_MD_AP, MD_APG_KUAP); + mtspr_uaccess_end(SPRN_MD_AP, MD_APG_KUAP); =20 return flags; } =20 static __always_inline void __restore_user_access(unsigned long flags) { - mtspr(SPRN_MD_AP, flags); + mtspr_uaccess_begin(SPRN_MD_AP, flags); } =20 static __always_inline bool diff --git a/arch/powerpc/include/asm/nohash/kup-booke.h b/arch/powerpc/inc= lude/asm/nohash/kup-booke.h index 416f3e0897d5..2967501c434e 100644 --- a/arch/powerpc/include/asm/nohash/kup-booke.h +++ b/arch/powerpc/include/asm/nohash/kup-booke.h @@ -64,13 +64,13 @@ static __always_inline unsigned long __kuap_get_and_ass= ert_locked(void) static __always_inline void __allow_user_access(void __user *to, const voi= d __user *from, unsigned long size, unsigned long dir) { - mtspr(SPRN_PID, current->thread.pid); + mtspr_uaccess_begin(SPRN_PID, current->thread.pid); isync(); } =20 static __always_inline void __prevent_user_access(unsigned long dir) { - mtspr(SPRN_PID, 0); + mtspr_uaccess_end(SPRN_PID, 0); isync(); } =20 @@ -78,7 +78,7 @@ static __always_inline unsigned long __prevent_user_acces= s_return(void) { unsigned long flags =3D mfspr(SPRN_PID); =20 - mtspr(SPRN_PID, 0); + mtspr_uaccess_end(SPRN_PID, 0); isync(); =20 return flags; @@ -87,7 +87,7 @@ static __always_inline unsigned long __prevent_user_acces= s_return(void) static __always_inline void __restore_user_access(unsigned long flags) { if (flags) { - mtspr(SPRN_PID, current->thread.pid); + mtspr_uaccess_begin(SPRN_PID, current->thread.pid); isync(); } } diff --git a/arch/powerpc/kexec/core_32.c b/arch/powerpc/kexec/core_32.c index c95f96850c9e..6e955f32e7c3 100644 --- a/arch/powerpc/kexec/core_32.c +++ b/arch/powerpc/kexec/core_32.c @@ -17,7 +17,7 @@ typedef void (*relocate_new_kernel_t)( unsigned long indirection_page, unsigned long reboot_code_buffer, - unsigned long start_address) __noreturn; + unsigned long start_address); =20 /* * This is a generic machine_kexec function suitable at least for @@ -61,6 +61,8 @@ void default_machine_kexec(struct kimage *image) /* now call it */ rnk =3D (relocate_new_kernel_t) reboot_code_buffer; (*rnk)(page_list, reboot_code_buffer_phys, image->start); + + unreachable(); /* For objtool */ } =20 int machine_kexec_prepare(struct kimage *image) diff --git a/tools/objtool/arch/powerpc/decode.c b/tools/objtool/arch/power= pc/decode.c index 53b55690f320..2ed5241eb7be 100644 --- a/tools/objtool/arch/powerpc/decode.c +++ b/tools/objtool/arch/powerpc/decode.c @@ -43,24 +43,94 @@ int arch_decode_instruction(struct objtool_file *file, = const struct section *sec unsigned long offset, unsigned int maxlen, struct instruction *insn) { - unsigned int opcode; + unsigned int opcode, xop; + unsigned int rs, ra, rb, bo, bi, to, uimm, simm, lk, aa; enum insn_type typ; unsigned long imm; u32 ins; =20 + if (file->elf->ehdr.e_flags & EF_PPC_RELOCATABLE_LIB) { + struct reloc *reloc; + + reloc =3D find_reloc_by_dest_range(file->elf, insn->sec, insn->offset, 4= ); + + if (reloc && reloc->type =3D=3D R_PPC_REL32 && + !strncmp(reloc->sym->sec->name, ".got2", 5)) { + insn->type =3D INSN_OTHER; + insn->ignore =3D true; + insn->len =3D 4; + + return 0; + } + } + ins =3D bswap_if_needed(file->elf, *(u32 *)(sec->data->d_buf + offset)); opcode =3D ins >> 26; - typ =3D INSN_OTHER; - imm =3D 0; + xop =3D (ins >> 1) & 0x3ff; + rs =3D bo =3D to =3D (ins >> 21) & 0x1f; + ra =3D bi =3D (ins >> 16) & 0x1f; + rb =3D (ins >> 11) & 0x1f; + uimm =3D simm =3D (ins >> 0) & 0xffff; + aa =3D ins & 2; + lk =3D ins & 1; =20 switch (opcode) { + case 3: + if (to =3D=3D 31 && ra =3D=3D 0 && simm =3D=3D 0) /* twi 31, r0, 0 */ + typ =3D INSN_BUG; + else + typ =3D INSN_OTHER; + break; + case 16: /* bc[l][a] */ + if (lk) /* bcl[a] */ + typ =3D INSN_OTHER; + else /* bc[a] */ + typ =3D INSN_JUMP_CONDITIONAL; + + imm =3D ins & 0xfffc; + if (imm & 0x8000) + imm -=3D 0x10000; + insn->immediate =3D imm | aa; + break; case 18: /* b[l][a] */ - if ((ins & 3) =3D=3D 1) /* bl */ + if (lk) /* bl[a] */ typ =3D INSN_CALL; + else /* b[a] */ + typ =3D INSN_JUMP_UNCONDITIONAL; =20 imm =3D ins & 0x3fffffc; if (imm & 0x2000000) imm -=3D 0x4000000; + insn->immediate =3D imm | aa; + break; + case 19: + if (xop =3D=3D 16 && bo =3D=3D 20 && bi =3D=3D 0) /* blr */ + typ =3D INSN_RETURN; + else if (xop =3D=3D 16) /* bclr */ + typ =3D INSN_RETURN_CONDITIONAL; + else if (xop =3D=3D 50) /* rfi */ + typ =3D INSN_JUMP_DYNAMIC; + else if (xop =3D=3D 528 && bo =3D=3D 20 && bi =3D=3D 0 && !lk) /* bctr */ + typ =3D INSN_JUMP_DYNAMIC; + else if (xop =3D=3D 528 && bo =3D=3D 20 && bi =3D=3D 0 && lk) /* bctrl */ + typ =3D INSN_CALL_DYNAMIC; + else + typ =3D INSN_OTHER; + break; + case 24: + if (rs =3D=3D 0 && ra =3D=3D 0 && uimm =3D=3D 0) + typ =3D INSN_NOP; + else + typ =3D INSN_OTHER; + break; + case 31: + if (xop =3D=3D 4 && to =3D=3D 31 && ra =3D=3D 0 && rb =3D=3D 0) /* trap = */ + typ =3D INSN_BUG; + else + typ =3D INSN_OTHER; + break; + default: + typ =3D INSN_OTHER; break; } =20 @@ -70,13 +140,15 @@ int arch_decode_instruction(struct objtool_file *file,= const struct section *sec insn->len =3D 4; =20 insn->type =3D typ; - insn->immediate =3D imm; =20 return 0; } =20 unsigned long arch_jump_destination(struct instruction *insn) { + if (insn->immediate & 2) + return insn->immediate & ~2; + return insn->offset + insn->immediate; } =20 diff --git a/tools/objtool/arch/powerpc/special.c b/tools/objtool/arch/powe= rpc/special.c index 979b555b16ea..be37f4b455dc 100644 --- a/tools/objtool/arch/powerpc/special.c +++ b/tools/objtool/arch/powerpc/special.c @@ -15,5 +15,45 @@ bool arch_support_alt_relocation(struct special_alt *spe= cial_alt, struct reloc *arch_find_switch_table(struct objtool_file *file, struct instruction *insn, bool *is_rel) { - exit(-1); + struct reloc *text_reloc, *rodata_reloc; + struct section *table_sec; + unsigned long table_offset; + + /* look for a relocation which references .rodata */ + text_reloc =3D find_reloc_by_dest_range(file->elf, insn->sec, + insn->offset, insn->len); + if (!text_reloc || text_reloc->sym->type !=3D STT_SECTION || + !text_reloc->sym->sec->rodata) + return NULL; + + table_offset =3D text_reloc->addend; + table_sec =3D text_reloc->sym->sec; + + /* + * Make sure the .rodata address isn't associated with a + * symbol. GCC jump tables are anonymous data. + * + * Also support C jump tables which are in the same format as + * switch jump tables. For objtool to recognize them, they + * need to be placed in the C_JUMP_TABLE_SECTION section. They + * have symbols associated with them. + */ + if (find_symbol_containing(table_sec, table_offset)) { + if (strcmp(table_sec->name, C_JUMP_TABLE_SECTION)) + return NULL; + *is_rel =3D false; + } else { + *is_rel =3D true; + } + + /* + * Each table entry has a rela associated with it. The rela + * should reference text in the same function as the original + * instruction. + */ + rodata_reloc =3D find_reloc_by_dest(file->elf, table_sec, table_offset); + if (!rodata_reloc) + return NULL; + + return rodata_reloc; } diff --git a/tools/objtool/check.c b/tools/objtool/check.c index f850ab892ad5..8ac5711a055f 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -218,6 +218,7 @@ static bool __dead_end_function(struct objtool_file *fi= le, struct symbol *func, "kthread_exit", "kunit_try_catch_throw", "lbug_with_loc", + "longjmp", "machine_real_restart", "make_task_dead", "mpt_halt_firmware", @@ -230,7 +231,9 @@ static bool __dead_end_function(struct objtool_file *fi= le, struct symbol *func, "sev_es_terminate", "snp_abort", "start_kernel", + "start_secondary_resume", "stop_this_cpu", + "unrecoverable_exception", "usercopy_abort", "x86_64_start_kernel", "x86_64_start_reservations", @@ -1335,6 +1338,8 @@ static const char *uaccess_safe_builtin[] =3D { "rep_stos_alternative", "rep_movs_alternative", "__copy_user_nocache", + "__copy_tofrom_user", + "__arch_clear_user", NULL }; =20 --=20 2.40.1