0001
0002 #ifndef _ASM_POWERPC_KUP_8XX_H_
0003 #define _ASM_POWERPC_KUP_8XX_H_
0004
0005 #include <asm/bug.h>
0006 #include <asm/mmu.h>
0007
0008 #ifdef CONFIG_PPC_KUAP
0009
0010 #ifndef __ASSEMBLY__
0011
0012 #include <linux/jump_label.h>
0013
0014 #include <asm/reg.h>
0015
0016 extern struct static_key_false disable_kuap_key;
0017
0018 static __always_inline bool kuap_is_disabled(void)
0019 {
0020 return static_branch_unlikely(&disable_kuap_key);
0021 }
0022
0023 static inline void __kuap_lock(void)
0024 {
0025 }
0026
0027 static inline void __kuap_save_and_lock(struct pt_regs *regs)
0028 {
0029 regs->kuap = mfspr(SPRN_MD_AP);
0030 mtspr(SPRN_MD_AP, MD_APG_KUAP);
0031 }
0032
0033 static inline void kuap_user_restore(struct pt_regs *regs)
0034 {
0035 }
0036
0037 static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap)
0038 {
0039 mtspr(SPRN_MD_AP, regs->kuap);
0040 }
0041
0042 static inline unsigned long __kuap_get_and_assert_locked(void)
0043 {
0044 unsigned long kuap;
0045
0046 kuap = mfspr(SPRN_MD_AP);
0047
0048 if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG))
0049 WARN_ON_ONCE(kuap >> 16 != MD_APG_KUAP >> 16);
0050
0051 return kuap;
0052 }
0053
0054 static inline void __allow_user_access(void __user *to, const void __user *from,
0055 unsigned long size, unsigned long dir)
0056 {
0057 mtspr(SPRN_MD_AP, MD_APG_INIT);
0058 }
0059
0060 static inline void __prevent_user_access(unsigned long dir)
0061 {
0062 mtspr(SPRN_MD_AP, MD_APG_KUAP);
0063 }
0064
0065 static inline unsigned long __prevent_user_access_return(void)
0066 {
0067 unsigned long flags;
0068
0069 flags = mfspr(SPRN_MD_AP);
0070
0071 mtspr(SPRN_MD_AP, MD_APG_KUAP);
0072
0073 return flags;
0074 }
0075
0076 static inline void __restore_user_access(unsigned long flags)
0077 {
0078 mtspr(SPRN_MD_AP, flags);
0079 }
0080
0081 static inline bool
0082 __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
0083 {
0084 return !((regs->kuap ^ MD_APG_KUAP) & 0xff000000);
0085 }
0086
0087 #endif
0088
0089 #endif
0090
0091 #endif