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 7 #ifdef CONFIG_PPC_KUAP 8 9 #ifdef __ASSEMBLY__ 10 11 .macro kuap_save_and_lock sp, thread, gpr1, gpr2, gpr3 12 lis \gpr2, MD_APG_KUAP@h /* only APG0 and APG1 are used */ 13 mfspr \gpr1, SPRN_MD_AP 14 mtspr SPRN_MD_AP, \gpr2 15 stw \gpr1, STACK_REGS_KUAP(\sp) 16 .endm 17 18 .macro kuap_restore sp, current, gpr1, gpr2, gpr3 19 lwz \gpr1, STACK_REGS_KUAP(\sp) 20 mtspr SPRN_MD_AP, \gpr1 21 .endm 22 23 .macro kuap_check current, gpr 24 #ifdef CONFIG_PPC_KUAP_DEBUG 25 mfspr \gpr, SPRN_MD_AP 26 rlwinm \gpr, \gpr, 16, 0xffff 27 999: twnei \gpr, MD_APG_KUAP@h 28 EMIT_BUG_ENTRY 999b, __FILE__, __LINE__, (BUGFLAG_WARNING | BUGFLAG_ONCE) 29 #endif 30 .endm 31 32 #else /* !__ASSEMBLY__ */ 33 34 #include <asm/reg.h> 35 36 static inline void allow_user_access(void __user *to, const void __user *from, 37 unsigned long size) 38 { 39 mtspr(SPRN_MD_AP, MD_APG_INIT); 40 } 41 42 static inline void prevent_user_access(void __user *to, const void __user *from, 43 unsigned long size) 44 { 45 mtspr(SPRN_MD_AP, MD_APG_KUAP); 46 } 47 48 static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write) 49 { 50 return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xf0000000), 51 "Bug: fault blocked by AP register !"); 52 } 53 54 #endif /* !__ASSEMBLY__ */ 55 56 #endif /* CONFIG_PPC_KUAP */ 57 58 #endif /* _ASM_POWERPC_KUP_8XX_H_ */ 59