kup-booke.h (2023B)
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _ASM_POWERPC_KUP_BOOKE_H_ 3#define _ASM_POWERPC_KUP_BOOKE_H_ 4 5#include <asm/bug.h> 6 7#ifdef CONFIG_PPC_KUAP 8 9#ifdef __ASSEMBLY__ 10 11.macro kuap_check_amr gpr1, gpr2 12.endm 13 14#else 15 16#include <linux/jump_label.h> 17#include <linux/sched.h> 18 19#include <asm/reg.h> 20 21extern struct static_key_false disable_kuap_key; 22 23static __always_inline bool kuap_is_disabled(void) 24{ 25 return static_branch_unlikely(&disable_kuap_key); 26} 27 28static inline void __kuap_lock(void) 29{ 30 mtspr(SPRN_PID, 0); 31 isync(); 32} 33 34static inline void __kuap_save_and_lock(struct pt_regs *regs) 35{ 36 regs->kuap = mfspr(SPRN_PID); 37 mtspr(SPRN_PID, 0); 38 isync(); 39} 40 41static inline void kuap_user_restore(struct pt_regs *regs) 42{ 43 if (kuap_is_disabled()) 44 return; 45 46 mtspr(SPRN_PID, current->thread.pid); 47 48 /* Context synchronisation is performed by rfi */ 49} 50 51static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap) 52{ 53 if (regs->kuap) 54 mtspr(SPRN_PID, current->thread.pid); 55 56 /* Context synchronisation is performed by rfi */ 57} 58 59static inline unsigned long __kuap_get_and_assert_locked(void) 60{ 61 unsigned long kuap = mfspr(SPRN_PID); 62 63 if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG)) 64 WARN_ON_ONCE(kuap); 65 66 return kuap; 67} 68 69static inline void __allow_user_access(void __user *to, const void __user *from, 70 unsigned long size, unsigned long dir) 71{ 72 mtspr(SPRN_PID, current->thread.pid); 73 isync(); 74} 75 76static inline void __prevent_user_access(unsigned long dir) 77{ 78 mtspr(SPRN_PID, 0); 79 isync(); 80} 81 82static inline unsigned long __prevent_user_access_return(void) 83{ 84 unsigned long flags = mfspr(SPRN_PID); 85 86 mtspr(SPRN_PID, 0); 87 isync(); 88 89 return flags; 90} 91 92static inline void __restore_user_access(unsigned long flags) 93{ 94 if (flags) { 95 mtspr(SPRN_PID, current->thread.pid); 96 isync(); 97 } 98} 99 100static inline bool 101__bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) 102{ 103 return !regs->kuap; 104} 105 106#endif /* !__ASSEMBLY__ */ 107 108#endif /* CONFIG_PPC_KUAP */ 109 110#endif /* _ASM_POWERPC_KUP_BOOKE_H_ */