Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _ASM_POWERPC_KUP_H_
0003 #define _ASM_POWERPC_KUP_H_
0004 
0005 #define KUAP_READ   1
0006 #define KUAP_WRITE  2
0007 #define KUAP_READ_WRITE (KUAP_READ | KUAP_WRITE)
0008 
0009 #ifdef CONFIG_PPC_BOOK3S_64
0010 #include <asm/book3s/64/kup.h>
0011 #endif
0012 
0013 #ifdef CONFIG_PPC_8xx
0014 #include <asm/nohash/32/kup-8xx.h>
0015 #endif
0016 
0017 #ifdef CONFIG_BOOKE_OR_40x
0018 #include <asm/nohash/kup-booke.h>
0019 #endif
0020 
0021 #ifdef CONFIG_PPC_BOOK3S_32
0022 #include <asm/book3s/32/kup.h>
0023 #endif
0024 
0025 #ifdef __ASSEMBLY__
0026 #ifndef CONFIG_PPC_KUAP
0027 .macro kuap_check_amr   gpr1, gpr2
0028 .endm
0029 
0030 #endif
0031 
0032 #else /* !__ASSEMBLY__ */
0033 
0034 extern bool disable_kuep;
0035 extern bool disable_kuap;
0036 
0037 #include <linux/pgtable.h>
0038 
0039 void setup_kup(void);
0040 void setup_kuep(bool disabled);
0041 
0042 #ifdef CONFIG_PPC_KUAP
0043 void setup_kuap(bool disabled);
0044 #else
0045 static inline void setup_kuap(bool disabled) { }
0046 
0047 static __always_inline bool kuap_is_disabled(void) { return true; }
0048 
0049 static inline bool
0050 __bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
0051 {
0052     return false;
0053 }
0054 
0055 static inline void __kuap_lock(void) { }
0056 static inline void __kuap_save_and_lock(struct pt_regs *regs) { }
0057 static inline void kuap_user_restore(struct pt_regs *regs) { }
0058 static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) { }
0059 
0060 static inline unsigned long __kuap_get_and_assert_locked(void)
0061 {
0062     return 0;
0063 }
0064 
0065 /*
0066  * book3s/64/kup-radix.h defines these functions for the !KUAP case to flush
0067  * the L1D cache after user accesses. Only include the empty stubs for other
0068  * platforms.
0069  */
0070 #ifndef CONFIG_PPC_BOOK3S_64
0071 static inline void __allow_user_access(void __user *to, const void __user *from,
0072                        unsigned long size, unsigned long dir) { }
0073 static inline void __prevent_user_access(unsigned long dir) { }
0074 static inline unsigned long __prevent_user_access_return(void) { return 0UL; }
0075 static inline void __restore_user_access(unsigned long flags) { }
0076 #endif /* CONFIG_PPC_BOOK3S_64 */
0077 #endif /* CONFIG_PPC_KUAP */
0078 
0079 static __always_inline bool
0080 bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
0081 {
0082     if (kuap_is_disabled())
0083         return false;
0084 
0085     return __bad_kuap_fault(regs, address, is_write);
0086 }
0087 
0088 static __always_inline void kuap_assert_locked(void)
0089 {
0090     if (kuap_is_disabled())
0091         return;
0092 
0093     if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG))
0094         __kuap_get_and_assert_locked();
0095 }
0096 
0097 static __always_inline void kuap_lock(void)
0098 {
0099     if (kuap_is_disabled())
0100         return;
0101 
0102     __kuap_lock();
0103 }
0104 
0105 static __always_inline void kuap_save_and_lock(struct pt_regs *regs)
0106 {
0107     if (kuap_is_disabled())
0108         return;
0109 
0110     __kuap_save_and_lock(regs);
0111 }
0112 
0113 static __always_inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long amr)
0114 {
0115     if (kuap_is_disabled())
0116         return;
0117 
0118     __kuap_kernel_restore(regs, amr);
0119 }
0120 
0121 static __always_inline unsigned long kuap_get_and_assert_locked(void)
0122 {
0123     if (kuap_is_disabled())
0124         return 0;
0125 
0126     return __kuap_get_and_assert_locked();
0127 }
0128 
0129 #ifndef CONFIG_PPC_BOOK3S_64
0130 static __always_inline void allow_user_access(void __user *to, const void __user *from,
0131                      unsigned long size, unsigned long dir)
0132 {
0133     if (kuap_is_disabled())
0134         return;
0135 
0136     __allow_user_access(to, from, size, dir);
0137 }
0138 
0139 static __always_inline void prevent_user_access(unsigned long dir)
0140 {
0141     if (kuap_is_disabled())
0142         return;
0143 
0144     __prevent_user_access(dir);
0145 }
0146 
0147 static __always_inline unsigned long prevent_user_access_return(void)
0148 {
0149     if (kuap_is_disabled())
0150         return 0;
0151 
0152     return __prevent_user_access_return();
0153 }
0154 
0155 static __always_inline void restore_user_access(unsigned long flags)
0156 {
0157     if (kuap_is_disabled())
0158         return;
0159 
0160     __restore_user_access(flags);
0161 }
0162 #endif /* CONFIG_PPC_BOOK3S_64 */
0163 
0164 static __always_inline void allow_read_from_user(const void __user *from, unsigned long size)
0165 {
0166     barrier_nospec();
0167     allow_user_access(NULL, from, size, KUAP_READ);
0168 }
0169 
0170 static __always_inline void allow_write_to_user(void __user *to, unsigned long size)
0171 {
0172     allow_user_access(to, NULL, size, KUAP_WRITE);
0173 }
0174 
0175 static __always_inline void allow_read_write_user(void __user *to, const void __user *from,
0176                           unsigned long size)
0177 {
0178     barrier_nospec();
0179     allow_user_access(to, from, size, KUAP_READ_WRITE);
0180 }
0181 
0182 static __always_inline void prevent_read_from_user(const void __user *from, unsigned long size)
0183 {
0184     prevent_user_access(KUAP_READ);
0185 }
0186 
0187 static __always_inline void prevent_write_to_user(void __user *to, unsigned long size)
0188 {
0189     prevent_user_access(KUAP_WRITE);
0190 }
0191 
0192 static __always_inline void prevent_read_write_user(void __user *to, const void __user *from,
0193                             unsigned long size)
0194 {
0195     prevent_user_access(KUAP_READ_WRITE);
0196 }
0197 
0198 static __always_inline void prevent_current_access_user(void)
0199 {
0200     prevent_user_access(KUAP_READ_WRITE);
0201 }
0202 
0203 static __always_inline void prevent_current_read_from_user(void)
0204 {
0205     prevent_user_access(KUAP_READ);
0206 }
0207 
0208 static __always_inline void prevent_current_write_to_user(void)
0209 {
0210     prevent_user_access(KUAP_WRITE);
0211 }
0212 
0213 #endif /* !__ASSEMBLY__ */
0214 
0215 #endif /* _ASM_POWERPC_KUAP_H_ */