From nobody Mon Feb 9 10:34:32 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