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