Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

powerpc/kuap: KUAP enabling/disabling functions must be __always_inline

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+0x188
(.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 <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/ca5e50ddbec3867db5146ebddbc9a1dc0e443bc8.1689091022.git.christophe.leroy@csgroup.eu

authored by

Christophe Leroy and committed by
Michael Ellerman
eb52f66f 5222a1d5

+53 -52
+9 -9
arch/powerpc/include/asm/book3s/32/kup.h
··· 15 15 16 16 #define KUAP_NONE (~0UL) 17 17 18 - static inline void kuap_lock_one(unsigned long addr) 18 + static __always_inline void kuap_lock_one(unsigned long addr) 19 19 { 20 20 mtsr(mfsr(addr) | SR_KS, addr); 21 21 isync(); /* Context sync required after mtsr() */ 22 22 } 23 23 24 - static inline void kuap_unlock_one(unsigned long addr) 24 + static __always_inline void kuap_unlock_one(unsigned long addr) 25 25 { 26 26 mtsr(mfsr(addr) & ~SR_KS, addr); 27 27 isync(); /* Context sync required after mtsr() */ 28 28 } 29 29 30 - static inline void __kuap_save_and_lock(struct pt_regs *regs) 30 + static __always_inline void __kuap_save_and_lock(struct pt_regs *regs) 31 31 { 32 32 unsigned long kuap = current->thread.kuap; 33 33 ··· 40 40 } 41 41 #define __kuap_save_and_lock __kuap_save_and_lock 42 42 43 - static inline void kuap_user_restore(struct pt_regs *regs) 43 + static __always_inline void kuap_user_restore(struct pt_regs *regs) 44 44 { 45 45 } 46 46 47 - static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap) 47 + static __always_inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap) 48 48 { 49 49 if (unlikely(kuap != KUAP_NONE)) { 50 50 current->thread.kuap = KUAP_NONE; ··· 59 59 kuap_unlock_one(regs->kuap); 60 60 } 61 61 62 - static inline unsigned long __kuap_get_and_assert_locked(void) 62 + static __always_inline unsigned long __kuap_get_and_assert_locked(void) 63 63 { 64 64 unsigned long kuap = current->thread.kuap; 65 65 ··· 94 94 kuap_lock_one(kuap); 95 95 } 96 96 97 - static inline unsigned long __prevent_user_access_return(void) 97 + static __always_inline unsigned long __prevent_user_access_return(void) 98 98 { 99 99 unsigned long flags = current->thread.kuap; 100 100 ··· 106 106 return flags; 107 107 } 108 108 109 - static inline void __restore_user_access(unsigned long flags) 109 + static __always_inline void __restore_user_access(unsigned long flags) 110 110 { 111 111 if (flags != KUAP_NONE) { 112 112 current->thread.kuap = flags; ··· 114 114 } 115 115 } 116 116 117 - static inline bool 117 + static __always_inline bool 118 118 __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) 119 119 { 120 120 unsigned long kuap = regs->kuap;
+12 -11
arch/powerpc/include/asm/book3s/64/kup.h
··· 213 213 * access restrictions. Because of this ignore AMR value when accessing 214 214 * userspace via kernel thread. 215 215 */ 216 - static inline u64 current_thread_amr(void) 216 + static __always_inline u64 current_thread_amr(void) 217 217 { 218 218 if (current->thread.regs) 219 219 return current->thread.regs->amr; 220 220 return default_amr; 221 221 } 222 222 223 - static inline u64 current_thread_iamr(void) 223 + static __always_inline u64 current_thread_iamr(void) 224 224 { 225 225 if (current->thread.regs) 226 226 return current->thread.regs->iamr; ··· 230 230 231 231 #ifdef CONFIG_PPC_KUAP 232 232 233 - static inline void kuap_user_restore(struct pt_regs *regs) 233 + static __always_inline void kuap_user_restore(struct pt_regs *regs) 234 234 { 235 235 bool restore_amr = false, restore_iamr = false; 236 236 unsigned long amr, iamr; ··· 269 269 */ 270 270 } 271 271 272 - static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) 272 + static __always_inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) 273 273 { 274 274 if (likely(regs->amr == amr)) 275 275 return; ··· 285 285 */ 286 286 } 287 287 288 - static inline unsigned long __kuap_get_and_assert_locked(void) 288 + static __always_inline unsigned long __kuap_get_and_assert_locked(void) 289 289 { 290 290 unsigned long amr = mfspr(SPRN_AMR); 291 291 ··· 302 302 * because that would require an expensive read/modify write of the AMR. 303 303 */ 304 304 305 - static inline unsigned long get_kuap(void) 305 + static __always_inline unsigned long get_kuap(void) 306 306 { 307 307 /* 308 308 * We return AMR_KUAP_BLOCKED when we don't support KUAP because ··· 332 332 isync(); 333 333 } 334 334 335 - static inline bool __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) 335 + static __always_inline bool 336 + __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) 336 337 { 337 338 /* 338 339 * For radix this will be a storage protection fault (DSISR_PROTFAULT). ··· 376 375 377 376 #else /* CONFIG_PPC_KUAP */ 378 377 379 - static inline unsigned long get_kuap(void) 378 + static __always_inline unsigned long get_kuap(void) 380 379 { 381 380 return AMR_KUAP_BLOCKED; 382 381 } 383 382 384 - static inline void set_kuap(unsigned long value) { } 383 + static __always_inline void set_kuap(unsigned long value) { } 385 384 386 385 static __always_inline void allow_user_access(void __user *to, const void __user *from, 387 386 unsigned long size, unsigned long dir) ··· 396 395 do_uaccess_flush(); 397 396 } 398 397 399 - static inline unsigned long prevent_user_access_return(void) 398 + static __always_inline unsigned long prevent_user_access_return(void) 400 399 { 401 400 unsigned long flags = get_kuap(); 402 401 ··· 407 406 return flags; 408 407 } 409 408 410 - static inline void restore_user_access(unsigned long flags) 409 + static __always_inline void restore_user_access(unsigned long flags) 411 410 { 412 411 set_kuap(flags); 413 412 if (static_branch_unlikely(&uaccess_flush_key) && flags == AMR_KUAP_BLOCKED)
+8 -8
arch/powerpc/include/asm/kup.h
··· 57 57 58 58 static __always_inline bool kuap_is_disabled(void) { return true; } 59 59 60 - static inline bool 60 + static __always_inline bool 61 61 __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) 62 62 { 63 63 return false; 64 64 } 65 65 66 - static inline void kuap_user_restore(struct pt_regs *regs) { } 67 - static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) { } 66 + static __always_inline void kuap_user_restore(struct pt_regs *regs) { } 67 + static __always_inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) { } 68 68 69 69 /* 70 70 * book3s/64/kup-radix.h defines these functions for the !KUAP case to flush ··· 72 72 * platforms. 73 73 */ 74 74 #ifndef CONFIG_PPC_BOOK3S_64 75 - static inline void __allow_user_access(void __user *to, const void __user *from, 76 - unsigned long size, unsigned long dir) { } 77 - static inline void __prevent_user_access(unsigned long dir) { } 78 - static inline unsigned long __prevent_user_access_return(void) { return 0UL; } 79 - static inline void __restore_user_access(unsigned long flags) { } 75 + static __always_inline void __allow_user_access(void __user *to, const void __user *from, 76 + unsigned long size, unsigned long dir) { } 77 + static __always_inline void __prevent_user_access(unsigned long dir) { } 78 + static __always_inline unsigned long __prevent_user_access_return(void) { return 0UL; } 79 + static __always_inline void __restore_user_access(unsigned long flags) { } 80 80 #endif /* CONFIG_PPC_BOOK3S_64 */ 81 81 #endif /* CONFIG_PPC_KUAP */ 82 82
+10 -10
arch/powerpc/include/asm/nohash/32/kup-8xx.h
··· 11 11 12 12 #include <asm/reg.h> 13 13 14 - static inline void __kuap_save_and_lock(struct pt_regs *regs) 14 + static __always_inline void __kuap_save_and_lock(struct pt_regs *regs) 15 15 { 16 16 regs->kuap = mfspr(SPRN_MD_AP); 17 17 mtspr(SPRN_MD_AP, MD_APG_KUAP); 18 18 } 19 19 #define __kuap_save_and_lock __kuap_save_and_lock 20 20 21 - static inline void kuap_user_restore(struct pt_regs *regs) 21 + static __always_inline void kuap_user_restore(struct pt_regs *regs) 22 22 { 23 23 } 24 24 25 - static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap) 25 + static __always_inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap) 26 26 { 27 27 mtspr(SPRN_MD_AP, regs->kuap); 28 28 } 29 29 30 30 #ifdef CONFIG_PPC_KUAP_DEBUG 31 - static inline unsigned long __kuap_get_and_assert_locked(void) 31 + static __always_inline unsigned long __kuap_get_and_assert_locked(void) 32 32 { 33 33 WARN_ON_ONCE(mfspr(SPRN_MD_AP) >> 16 != MD_APG_KUAP >> 16); 34 34 ··· 37 37 #define __kuap_get_and_assert_locked __kuap_get_and_assert_locked 38 38 #endif 39 39 40 - static inline void __allow_user_access(void __user *to, const void __user *from, 41 - unsigned long size, unsigned long dir) 40 + static __always_inline void __allow_user_access(void __user *to, const void __user *from, 41 + unsigned long size, unsigned long dir) 42 42 { 43 43 mtspr(SPRN_MD_AP, MD_APG_INIT); 44 44 } 45 45 46 - static inline void __prevent_user_access(unsigned long dir) 46 + static __always_inline void __prevent_user_access(unsigned long dir) 47 47 { 48 48 mtspr(SPRN_MD_AP, MD_APG_KUAP); 49 49 } 50 50 51 - static inline unsigned long __prevent_user_access_return(void) 51 + static __always_inline unsigned long __prevent_user_access_return(void) 52 52 { 53 53 unsigned long flags; 54 54 ··· 59 59 return flags; 60 60 } 61 61 62 - static inline void __restore_user_access(unsigned long flags) 62 + static __always_inline void __restore_user_access(unsigned long flags) 63 63 { 64 64 mtspr(SPRN_MD_AP, flags); 65 65 } 66 66 67 - static inline bool 67 + static __always_inline bool 68 68 __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) 69 69 { 70 70 return !((regs->kuap ^ MD_APG_KUAP) & 0xff000000);
+11 -11
arch/powerpc/include/asm/nohash/kup-booke.h
··· 17 17 18 18 #include <asm/reg.h> 19 19 20 - static inline void __kuap_lock(void) 20 + static __always_inline void __kuap_lock(void) 21 21 { 22 22 mtspr(SPRN_PID, 0); 23 23 isync(); 24 24 } 25 25 #define __kuap_lock __kuap_lock 26 26 27 - static inline void __kuap_save_and_lock(struct pt_regs *regs) 27 + static __always_inline void __kuap_save_and_lock(struct pt_regs *regs) 28 28 { 29 29 regs->kuap = mfspr(SPRN_PID); 30 30 mtspr(SPRN_PID, 0); ··· 32 32 } 33 33 #define __kuap_save_and_lock __kuap_save_and_lock 34 34 35 - static inline void kuap_user_restore(struct pt_regs *regs) 35 + static __always_inline void kuap_user_restore(struct pt_regs *regs) 36 36 { 37 37 if (kuap_is_disabled()) 38 38 return; ··· 42 42 /* Context synchronisation is performed by rfi */ 43 43 } 44 44 45 - static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap) 45 + static __always_inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap) 46 46 { 47 47 if (regs->kuap) 48 48 mtspr(SPRN_PID, current->thread.pid); ··· 51 51 } 52 52 53 53 #ifdef CONFIG_PPC_KUAP_DEBUG 54 - static inline unsigned long __kuap_get_and_assert_locked(void) 54 + static __always_inline unsigned long __kuap_get_and_assert_locked(void) 55 55 { 56 56 WARN_ON_ONCE(mfspr(SPRN_PID)); 57 57 ··· 60 60 #define __kuap_get_and_assert_locked __kuap_get_and_assert_locked 61 61 #endif 62 62 63 - static inline void __allow_user_access(void __user *to, const void __user *from, 64 - unsigned long size, unsigned long dir) 63 + static __always_inline void __allow_user_access(void __user *to, const void __user *from, 64 + unsigned long size, unsigned long dir) 65 65 { 66 66 mtspr(SPRN_PID, current->thread.pid); 67 67 isync(); 68 68 } 69 69 70 - static inline void __prevent_user_access(unsigned long dir) 70 + static __always_inline void __prevent_user_access(unsigned long dir) 71 71 { 72 72 mtspr(SPRN_PID, 0); 73 73 isync(); 74 74 } 75 75 76 - static inline unsigned long __prevent_user_access_return(void) 76 + static __always_inline unsigned long __prevent_user_access_return(void) 77 77 { 78 78 unsigned long flags = mfspr(SPRN_PID); 79 79 ··· 83 83 return flags; 84 84 } 85 85 86 - static inline void __restore_user_access(unsigned long flags) 86 + static __always_inline void __restore_user_access(unsigned long flags) 87 87 { 88 88 if (flags) { 89 89 mtspr(SPRN_PID, current->thread.pid); ··· 91 91 } 92 92 } 93 93 94 - static inline bool 94 + static __always_inline bool 95 95 __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) 96 96 { 97 97 return !regs->kuap;
+3 -3
arch/powerpc/include/asm/uaccess.h
··· 386 386 extern long __copy_from_user_flushcache(void *dst, const void __user *src, 387 387 unsigned size); 388 388 389 - static __must_check inline bool user_access_begin(const void __user *ptr, size_t len) 389 + static __must_check __always_inline bool user_access_begin(const void __user *ptr, size_t len) 390 390 { 391 391 if (unlikely(!access_ok(ptr, len))) 392 392 return false; ··· 401 401 #define user_access_save prevent_user_access_return 402 402 #define user_access_restore restore_user_access 403 403 404 - static __must_check inline bool 404 + static __must_check __always_inline bool 405 405 user_read_access_begin(const void __user *ptr, size_t len) 406 406 { 407 407 if (unlikely(!access_ok(ptr, len))) ··· 415 415 #define user_read_access_begin user_read_access_begin 416 416 #define user_read_access_end prevent_current_read_from_user 417 417 418 - static __must_check inline bool 418 + static __must_check __always_inline bool 419 419 user_write_access_begin(const void __user *ptr, size_t len) 420 420 { 421 421 if (unlikely(!access_ok(ptr, len)))