xref: /OK3568_Linux_fs/kernel/arch/powerpc/include/asm/kup.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef _ASM_POWERPC_KUP_H_
3*4882a593Smuzhiyun #define _ASM_POWERPC_KUP_H_
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #define KUAP_READ	1
6*4882a593Smuzhiyun #define KUAP_WRITE	2
7*4882a593Smuzhiyun #define KUAP_READ_WRITE	(KUAP_READ | KUAP_WRITE)
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun  * For prevent_user_access() only.
10*4882a593Smuzhiyun  * Use the current saved situation instead of the to/from/size params.
11*4882a593Smuzhiyun  * Used on book3s/32
12*4882a593Smuzhiyun  */
13*4882a593Smuzhiyun #define KUAP_CURRENT_READ	4
14*4882a593Smuzhiyun #define KUAP_CURRENT_WRITE	8
15*4882a593Smuzhiyun #define KUAP_CURRENT		(KUAP_CURRENT_READ | KUAP_CURRENT_WRITE)
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #ifdef CONFIG_PPC_BOOK3S_64
18*4882a593Smuzhiyun #include <asm/book3s/64/kup-radix.h>
19*4882a593Smuzhiyun #endif
20*4882a593Smuzhiyun #ifdef CONFIG_PPC_8xx
21*4882a593Smuzhiyun #include <asm/nohash/32/kup-8xx.h>
22*4882a593Smuzhiyun #endif
23*4882a593Smuzhiyun #ifdef CONFIG_PPC_BOOK3S_32
24*4882a593Smuzhiyun #include <asm/book3s/32/kup.h>
25*4882a593Smuzhiyun #endif
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #ifdef __ASSEMBLY__
28*4882a593Smuzhiyun #ifndef CONFIG_PPC_KUAP
29*4882a593Smuzhiyun .macro kuap_save_and_lock	sp, thread, gpr1, gpr2, gpr3
30*4882a593Smuzhiyun .endm
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun .macro kuap_restore	sp, current, gpr1, gpr2, gpr3
33*4882a593Smuzhiyun .endm
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun .macro kuap_check	current, gpr
36*4882a593Smuzhiyun .endm
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun .macro kuap_check_amr	gpr1, gpr2
39*4882a593Smuzhiyun .endm
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #endif
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #else /* !__ASSEMBLY__ */
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun #include <linux/pgtable.h>
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun void setup_kup(void);
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #ifdef CONFIG_PPC_KUEP
50*4882a593Smuzhiyun void setup_kuep(bool disabled);
51*4882a593Smuzhiyun #else
setup_kuep(bool disabled)52*4882a593Smuzhiyun static inline void setup_kuep(bool disabled) { }
53*4882a593Smuzhiyun #endif /* CONFIG_PPC_KUEP */
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun #ifdef CONFIG_PPC_KUAP
56*4882a593Smuzhiyun void setup_kuap(bool disabled);
57*4882a593Smuzhiyun #else
setup_kuap(bool disabled)58*4882a593Smuzhiyun static inline void setup_kuap(bool disabled) { }
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun static inline bool
bad_kuap_fault(struct pt_regs * regs,unsigned long address,bool is_write)61*4882a593Smuzhiyun bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun 	return false;
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun 
kuap_check_amr(void)66*4882a593Smuzhiyun static inline void kuap_check_amr(void) { }
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun /*
69*4882a593Smuzhiyun  * book3s/64/kup-radix.h defines these functions for the !KUAP case to flush
70*4882a593Smuzhiyun  * the L1D cache after user accesses. Only include the empty stubs for other
71*4882a593Smuzhiyun  * platforms.
72*4882a593Smuzhiyun  */
73*4882a593Smuzhiyun #ifndef CONFIG_PPC_BOOK3S_64
allow_user_access(void __user * to,const void __user * from,unsigned long size,unsigned long dir)74*4882a593Smuzhiyun static inline void allow_user_access(void __user *to, const void __user *from,
75*4882a593Smuzhiyun 				     unsigned long size, unsigned long dir) { }
prevent_user_access(void __user * to,const void __user * from,unsigned long size,unsigned long dir)76*4882a593Smuzhiyun static inline void prevent_user_access(void __user *to, const void __user *from,
77*4882a593Smuzhiyun 				       unsigned long size, unsigned long dir) { }
prevent_user_access_return(void)78*4882a593Smuzhiyun static inline unsigned long prevent_user_access_return(void) { return 0UL; }
restore_user_access(unsigned long flags)79*4882a593Smuzhiyun static inline void restore_user_access(unsigned long flags) { }
80*4882a593Smuzhiyun #endif /* CONFIG_PPC_BOOK3S_64 */
81*4882a593Smuzhiyun #endif /* CONFIG_PPC_KUAP */
82*4882a593Smuzhiyun 
allow_read_from_user(const void __user * from,unsigned long size)83*4882a593Smuzhiyun static inline void allow_read_from_user(const void __user *from, unsigned long size)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun 	allow_user_access(NULL, from, size, KUAP_READ);
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun 
allow_write_to_user(void __user * to,unsigned long size)88*4882a593Smuzhiyun static inline void allow_write_to_user(void __user *to, unsigned long size)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun 	allow_user_access(to, NULL, size, KUAP_WRITE);
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
allow_read_write_user(void __user * to,const void __user * from,unsigned long size)93*4882a593Smuzhiyun static inline void allow_read_write_user(void __user *to, const void __user *from,
94*4882a593Smuzhiyun 					 unsigned long size)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun 	allow_user_access(to, from, size, KUAP_READ_WRITE);
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun 
prevent_read_from_user(const void __user * from,unsigned long size)99*4882a593Smuzhiyun static inline void prevent_read_from_user(const void __user *from, unsigned long size)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun 	prevent_user_access(NULL, from, size, KUAP_READ);
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun 
prevent_write_to_user(void __user * to,unsigned long size)104*4882a593Smuzhiyun static inline void prevent_write_to_user(void __user *to, unsigned long size)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun 	prevent_user_access(to, NULL, size, KUAP_WRITE);
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun 
prevent_read_write_user(void __user * to,const void __user * from,unsigned long size)109*4882a593Smuzhiyun static inline void prevent_read_write_user(void __user *to, const void __user *from,
110*4882a593Smuzhiyun 					   unsigned long size)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun 	prevent_user_access(to, from, size, KUAP_READ_WRITE);
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun 
prevent_current_access_user(void)115*4882a593Smuzhiyun static inline void prevent_current_access_user(void)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun 	prevent_user_access(NULL, NULL, ~0UL, KUAP_CURRENT);
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
prevent_current_read_from_user(void)120*4882a593Smuzhiyun static inline void prevent_current_read_from_user(void)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	prevent_user_access(NULL, NULL, ~0UL, KUAP_CURRENT_READ);
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
prevent_current_write_to_user(void)125*4882a593Smuzhiyun static inline void prevent_current_write_to_user(void)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun 	prevent_user_access(NULL, NULL, ~0UL, KUAP_CURRENT_WRITE);
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun #endif /* !__ASSEMBLY__ */
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun #endif /* _ASM_POWERPC_KUAP_H_ */
133