1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _ASM_POWERPC_KUP_8XX_H_ 3 #define _ASM_POWERPC_KUP_8XX_H_ 4 5 #include <asm/bug.h> 6 #include <asm/mmu.h> 7 8 #ifdef CONFIG_PPC_KUAP 9 10 #ifndef __ASSEMBLY__ 11 12 #include <linux/jump_label.h> 13 14 #include <asm/reg.h> 15 16 extern struct static_key_false disable_kuap_key; 17 18 static __always_inline bool kuap_is_disabled(void) 19 { 20 return static_branch_unlikely(&disable_kuap_key); 21 } 22 23 static inline void __kuap_lock(void) 24 { 25 } 26 27 static inline void __kuap_save_and_lock(struct pt_regs *regs) 28 { 29 regs->kuap = mfspr(SPRN_MD_AP); 30 mtspr(SPRN_MD_AP, MD_APG_KUAP); 31 } 32 33 static inline void kuap_user_restore(struct pt_regs *regs) 34 { 35 } 36 37 static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap) 38 { 39 mtspr(SPRN_MD_AP, regs->kuap); 40 } 41 42 static inline unsigned long __kuap_get_and_assert_locked(void) 43 { 44 unsigned long kuap; 45 46 kuap = mfspr(SPRN_MD_AP); 47 48 if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG)) 49 WARN_ON_ONCE(kuap >> 16 != MD_APG_KUAP >> 16); 50 51 return kuap; 52 } 53 54 static inline void __allow_user_access(void __user *to, const void __user *from, 55 unsigned long size, unsigned long dir) 56 { 57 mtspr(SPRN_MD_AP, MD_APG_INIT); 58 } 59 60 static inline void __prevent_user_access(unsigned long dir) 61 { 62 mtspr(SPRN_MD_AP, MD_APG_KUAP); 63 } 64 65 static inline unsigned long __prevent_user_access_return(void) 66 { 67 unsigned long flags; 68 69 flags = mfspr(SPRN_MD_AP); 70 71 mtspr(SPRN_MD_AP, MD_APG_KUAP); 72 73 return flags; 74 } 75 76 static inline void __restore_user_access(unsigned long flags) 77 { 78 mtspr(SPRN_MD_AP, flags); 79 } 80 81 static inline bool 82 __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) 83 { 84 return !((regs->kuap ^ MD_APG_KUAP) & 0xff000000); 85 } 86 87 #endif /* !__ASSEMBLY__ */ 88 89 #endif /* CONFIG_PPC_KUAP */ 90 91 #endif /* _ASM_POWERPC_KUP_8XX_H_ */ 92