1
2#ifndef _ASM_POWERPC_KUP_H_
3#define _ASM_POWERPC_KUP_H_
4
5#define KUAP_READ 1
6#define KUAP_WRITE 2
7#define KUAP_READ_WRITE (KUAP_READ | KUAP_WRITE)
8
9#ifdef CONFIG_PPC_BOOK3S_64
10#include <asm/book3s/64/kup.h>
11#endif
12
13#ifdef CONFIG_PPC_8xx
14#include <asm/nohash/32/kup-8xx.h>
15#endif
16
17#ifdef CONFIG_PPC_BOOK3S_32
18#include <asm/book3s/32/kup.h>
19#endif
20
21#ifdef __ASSEMBLY__
22#ifndef CONFIG_PPC_KUAP
23.macro kuap_check_amr gpr1, gpr2
24.endm
25
26#endif
27
28#else
29
30extern bool disable_kuep;
31extern bool disable_kuap;
32
33#include <linux/pgtable.h>
34
35#ifdef CONFIG_PPC_KUEP
36void setup_kuep(bool disabled);
37#else
38static inline void setup_kuep(bool disabled) { }
39#endif
40
41#ifndef CONFIG_PPC_BOOK3S_32
42static inline void kuep_lock(void) { }
43static inline void kuep_unlock(void) { }
44#endif
45
46#ifdef CONFIG_PPC_KUAP
47void setup_kuap(bool disabled);
48#else
49static inline void setup_kuap(bool disabled) { }
50
51static inline bool
52bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
53{
54 return false;
55}
56
57static inline void kuap_assert_locked(void) { }
58static inline void kuap_save_and_lock(struct pt_regs *regs) { }
59static inline void kuap_user_restore(struct pt_regs *regs) { }
60static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) { }
61
62static inline unsigned long kuap_get_and_assert_locked(void)
63{
64 return 0;
65}
66
67
68
69
70
71
72#ifndef CONFIG_PPC_BOOK3S_64
73static inline void allow_user_access(void __user *to, const void __user *from,
74 unsigned long size, unsigned long dir) { }
75static inline void prevent_user_access(unsigned long dir) { }
76static inline unsigned long prevent_user_access_return(void) { return 0UL; }
77static inline void restore_user_access(unsigned long flags) { }
78#endif
79#endif
80
81static __always_inline void setup_kup(void)
82{
83 setup_kuep(disable_kuep);
84 setup_kuap(disable_kuap);
85}
86
87static __always_inline void allow_read_from_user(const void __user *from, unsigned long size)
88{
89 barrier_nospec();
90 allow_user_access(NULL, from, size, KUAP_READ);
91}
92
93static __always_inline void allow_write_to_user(void __user *to, unsigned long size)
94{
95 allow_user_access(to, NULL, size, KUAP_WRITE);
96}
97
98static __always_inline void allow_read_write_user(void __user *to, const void __user *from,
99 unsigned long size)
100{
101 barrier_nospec();
102 allow_user_access(to, from, size, KUAP_READ_WRITE);
103}
104
105static __always_inline void prevent_read_from_user(const void __user *from, unsigned long size)
106{
107 prevent_user_access(KUAP_READ);
108}
109
110static __always_inline void prevent_write_to_user(void __user *to, unsigned long size)
111{
112 prevent_user_access(KUAP_WRITE);
113}
114
115static __always_inline void prevent_read_write_user(void __user *to, const void __user *from,
116 unsigned long size)
117{
118 prevent_user_access(KUAP_READ_WRITE);
119}
120
121static __always_inline void prevent_current_access_user(void)
122{
123 prevent_user_access(KUAP_READ_WRITE);
124}
125
126static __always_inline void prevent_current_read_from_user(void)
127{
128 prevent_user_access(KUAP_READ);
129}
130
131static __always_inline void prevent_current_write_to_user(void)
132{
133 prevent_user_access(KUAP_WRITE);
134}
135
136#endif
137
138#endif
139