1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_POWERPC_KUP_8XX_H_
3 #define _ASM_POWERPC_KUP_8XX_H_
12 #include <linux/jump_label.h>
16 extern struct static_key_false disable_kuap_key;
18 static __always_inline bool kuap_is_disabled(void)
20 return static_branch_unlikely(&disable_kuap_key);
23 static inline void kuap_save_and_lock(struct pt_regs *regs)
25 if (kuap_is_disabled())
28 regs->kuap = mfspr(SPRN_MD_AP);
29 mtspr(SPRN_MD_AP, MD_APG_KUAP);
32 static inline void kuap_user_restore(struct pt_regs *regs)
36 static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap)
38 if (kuap_is_disabled())
41 mtspr(SPRN_MD_AP, regs->kuap);
44 static inline unsigned long kuap_get_and_assert_locked(void)
48 if (kuap_is_disabled())
51 kuap = mfspr(SPRN_MD_AP);
53 if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG))
54 WARN_ON_ONCE(kuap >> 16 != MD_APG_KUAP >> 16);
59 static inline void kuap_assert_locked(void)
61 if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG) && !kuap_is_disabled())
62 kuap_get_and_assert_locked();
65 static inline void allow_user_access(void __user *to, const void __user *from,
66 unsigned long size, unsigned long dir)
68 if (kuap_is_disabled())
71 mtspr(SPRN_MD_AP, MD_APG_INIT);
74 static inline void prevent_user_access(unsigned long dir)
76 if (kuap_is_disabled())
79 mtspr(SPRN_MD_AP, MD_APG_KUAP);
82 static inline unsigned long prevent_user_access_return(void)
86 if (kuap_is_disabled())
89 flags = mfspr(SPRN_MD_AP);
91 mtspr(SPRN_MD_AP, MD_APG_KUAP);
96 static inline void restore_user_access(unsigned long flags)
98 if (kuap_is_disabled())
101 mtspr(SPRN_MD_AP, flags);
105 bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
107 if (kuap_is_disabled())
110 return !((regs->kuap ^ MD_APG_KUAP) & 0xff000000);
113 #endif /* !__ASSEMBLY__ */
115 #endif /* CONFIG_PPC_KUAP */
117 #endif /* _ASM_POWERPC_KUP_8XX_H_ */