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 <asm/reg.h> 13 14 static inline void kuap_save_and_lock(struct pt_regs *regs) 15 { 16 regs->kuap = mfspr(SPRN_MD_AP); 17 mtspr(SPRN_MD_AP, MD_APG_KUAP); 18 } 19 20 static inline void kuap_user_restore(struct pt_regs *regs) 21 { 22 } 23 24 static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap) 25 { 26 mtspr(SPRN_MD_AP, regs->kuap); 27 } 28 29 static inline unsigned long kuap_get_and_assert_locked(void) 30 { 31 unsigned long kuap = mfspr(SPRN_MD_AP); 32 33 if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG)) 34 WARN_ON_ONCE(kuap >> 16 != MD_APG_KUAP >> 16); 35 36 return kuap; 37 } 38 39 static inline void kuap_assert_locked(void) 40 { 41 if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG)) 42 kuap_get_and_assert_locked(); 43 } 44 45 static inline void allow_user_access(void __user *to, const void __user *from, 46 unsigned long size, unsigned long dir) 47 { 48 mtspr(SPRN_MD_AP, MD_APG_INIT); 49 } 50 51 static inline void prevent_user_access(void __user *to, const void __user *from, 52 unsigned long size, unsigned long dir) 53 { 54 mtspr(SPRN_MD_AP, MD_APG_KUAP); 55 } 56 57 static inline unsigned long prevent_user_access_return(void) 58 { 59 unsigned long flags = mfspr(SPRN_MD_AP); 60 61 mtspr(SPRN_MD_AP, MD_APG_KUAP); 62 63 return flags; 64 } 65 66 static inline void restore_user_access(unsigned long flags) 67 { 68 mtspr(SPRN_MD_AP, flags); 69 } 70 71 static inline bool 72 bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) 73 { 74 return !((regs->kuap ^ MD_APG_KUAP) & 0xff000000); 75 } 76 77 #endif /* !__ASSEMBLY__ */ 78 79 #endif /* CONFIG_PPC_KUAP */ 80 81 #endif /* _ASM_POWERPC_KUP_8XX_H_ */ 82