blob: fb2237809d63b46bf4040c7032cf41a0190c0787 [file] [log] [blame]
Christophe Leroy69795ca2019-04-18 16:51:18 +10001/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_POWERPC_KUP_H_
3#define _ASM_POWERPC_KUP_H_
4
Christophe Leroy1d8f7392020-01-24 11:54:41 +00005#define KUAP_READ 1
6#define KUAP_WRITE 2
7#define KUAP_READ_WRITE (KUAP_READ | KUAP_WRITE)
8
Michael Ellerman178d52c2020-11-19 23:43:53 +11009#ifdef CONFIG_PPC_BOOK3S_64
Aneesh Kumar K.V3b47b752020-11-27 10:14:07 +053010#include <asm/book3s/64/kup.h>
Michael Ellerman890274c2019-04-18 16:51:24 +100011#endif
Aneesh Kumar K.V3b47b752020-11-27 10:14:07 +053012
Christophe Leroy2679f9b2019-03-11 08:30:34 +000013#ifdef CONFIG_PPC_8xx
14#include <asm/nohash/32/kup-8xx.h>
15#endif
Aneesh Kumar K.V3b47b752020-11-27 10:14:07 +053016
Christophe Leroy43afcf82021-10-19 09:29:28 +020017#ifdef CONFIG_BOOKE_OR_40x
18#include <asm/nohash/kup-booke.h>
19#endif
20
Christophe Leroy31ed2b12019-03-11 08:30:35 +000021#ifdef CONFIG_PPC_BOOK3S_32
22#include <asm/book3s/32/kup.h>
23#endif
Michael Ellerman890274c2019-04-18 16:51:24 +100024
Christophe Leroye2fb9f52019-03-11 08:30:31 +000025#ifdef __ASSEMBLY__
26#ifndef CONFIG_PPC_KUAP
Michael Ellerman178d52c2020-11-19 23:43:53 +110027.macro kuap_check_amr gpr1, gpr2
28.endm
29
Christophe Leroye2fb9f52019-03-11 08:30:31 +000030#endif
31
32#else /* !__ASSEMBLY__ */
Christophe Leroy69795ca2019-04-18 16:51:18 +100033
Aneesh Kumar K.V61130e22020-12-02 10:08:54 +053034extern bool disable_kuep;
35extern bool disable_kuap;
36
Mike Rapoportca5999f2020-06-08 21:32:38 -070037#include <linux/pgtable.h>
Christophe Leroyde78a9c2019-04-18 16:51:20 +100038
Christophe Leroy6c1fa602021-10-19 09:29:12 +020039void setup_kup(void);
Christophe Leroy0fb1c252019-04-18 16:51:19 +100040void setup_kuep(bool disabled);
Christophe Leroy0fb1c252019-04-18 16:51:19 +100041
Christophe Leroyde78a9c2019-04-18 16:51:20 +100042#ifdef CONFIG_PPC_KUAP
43void setup_kuap(bool disabled);
44#else
45static inline void setup_kuap(bool disabled) { }
Nicholas Piggin9a32a7e2020-11-17 16:59:13 +110046
Christophe Leroyc252f382021-10-19 09:29:21 +020047static __always_inline bool kuap_is_disabled(void) { return true; }
48
Aneesh Kumar K.V475c8742020-12-08 08:45:39 +053049static inline bool
Christophe Leroyba454f92021-10-19 09:29:20 +020050__bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
Nicholas Piggin9a32a7e2020-11-17 16:59:13 +110051{
52 return false;
53}
54
Christophe Leroyba454f92021-10-19 09:29:20 +020055static inline void __kuap_assert_locked(void) { }
Christophe Leroy937fb702021-10-19 09:29:23 +020056static inline void __kuap_lock(void) { }
Christophe Leroyba454f92021-10-19 09:29:20 +020057static inline void __kuap_save_and_lock(struct pt_regs *regs) { }
Christophe Leroyad2d2342021-03-12 12:50:48 +000058static inline void kuap_user_restore(struct pt_regs *regs) { }
Christophe Leroyba454f92021-10-19 09:29:20 +020059static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) { }
Christophe Leroyad2d2342021-03-12 12:50:48 +000060
Christophe Leroyba454f92021-10-19 09:29:20 +020061static inline unsigned long __kuap_get_and_assert_locked(void)
Christophe Leroyad2d2342021-03-12 12:50:48 +000062{
63 return 0;
64}
Michael Ellerman178d52c2020-11-19 23:43:53 +110065
Nicholas Piggin9a32a7e2020-11-17 16:59:13 +110066/*
67 * book3s/64/kup-radix.h defines these functions for the !KUAP case to flush
68 * the L1D cache after user accesses. Only include the empty stubs for other
69 * platforms.
70 */
Michael Ellerman178d52c2020-11-19 23:43:53 +110071#ifndef CONFIG_PPC_BOOK3S_64
Christophe Leroyba454f92021-10-19 09:29:20 +020072static inline void __allow_user_access(void __user *to, const void __user *from,
73 unsigned long size, unsigned long dir) { }
74static inline void __prevent_user_access(unsigned long dir) { }
75static inline unsigned long __prevent_user_access_return(void) { return 0UL; }
76static inline void __restore_user_access(unsigned long flags) { }
Michael Ellerman178d52c2020-11-19 23:43:53 +110077#endif /* CONFIG_PPC_BOOK3S_64 */
Christophe Leroyde78a9c2019-04-18 16:51:20 +100078#endif /* CONFIG_PPC_KUAP */
79
Christophe Leroyba454f92021-10-19 09:29:20 +020080static __always_inline bool
81bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
82{
Christophe Leroyc252f382021-10-19 09:29:21 +020083 if (kuap_is_disabled())
84 return false;
85
Christophe Leroyba454f92021-10-19 09:29:20 +020086 return __bad_kuap_fault(regs, address, is_write);
87}
88
89static __always_inline void kuap_assert_locked(void)
90{
Christophe Leroyc252f382021-10-19 09:29:21 +020091 if (kuap_is_disabled())
92 return;
93
Christophe Leroy23419642021-10-19 09:29:22 +020094 if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG))
95 __kuap_get_and_assert_locked();
Christophe Leroyba454f92021-10-19 09:29:20 +020096}
97
Christophe Leroy937fb702021-10-19 09:29:23 +020098static __always_inline void kuap_lock(void)
99{
100 if (kuap_is_disabled())
101 return;
102
103 __kuap_lock();
104}
105
Christophe Leroyba454f92021-10-19 09:29:20 +0200106static __always_inline void kuap_save_and_lock(struct pt_regs *regs)
107{
Christophe Leroyc252f382021-10-19 09:29:21 +0200108 if (kuap_is_disabled())
109 return;
110
Christophe Leroyba454f92021-10-19 09:29:20 +0200111 __kuap_save_and_lock(regs);
112}
Christophe Leroyba454f92021-10-19 09:29:20 +0200113
114static __always_inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long amr)
115{
Christophe Leroyc252f382021-10-19 09:29:21 +0200116 if (kuap_is_disabled())
117 return;
118
Christophe Leroyba454f92021-10-19 09:29:20 +0200119 __kuap_kernel_restore(regs, amr);
120}
121
122static __always_inline unsigned long kuap_get_and_assert_locked(void)
123{
Christophe Leroyc252f382021-10-19 09:29:21 +0200124 if (kuap_is_disabled())
125 return 0;
126
Christophe Leroyba454f92021-10-19 09:29:20 +0200127 return __kuap_get_and_assert_locked();
128}
129
130#ifndef CONFIG_PPC_BOOK3S_64
131static __always_inline void allow_user_access(void __user *to, const void __user *from,
132 unsigned long size, unsigned long dir)
133{
Christophe Leroyc252f382021-10-19 09:29:21 +0200134 if (kuap_is_disabled())
135 return;
136
Christophe Leroyba454f92021-10-19 09:29:20 +0200137 __allow_user_access(to, from, size, dir);
138}
139
140static __always_inline void prevent_user_access(unsigned long dir)
141{
Christophe Leroyc252f382021-10-19 09:29:21 +0200142 if (kuap_is_disabled())
143 return;
144
Christophe Leroyba454f92021-10-19 09:29:20 +0200145 __prevent_user_access(dir);
146}
147
148static __always_inline unsigned long prevent_user_access_return(void)
149{
Christophe Leroyc252f382021-10-19 09:29:21 +0200150 if (kuap_is_disabled())
151 return 0;
152
Christophe Leroyba454f92021-10-19 09:29:20 +0200153 return __prevent_user_access_return();
154}
155
156static __always_inline void restore_user_access(unsigned long flags)
157{
Christophe Leroyc252f382021-10-19 09:29:21 +0200158 if (kuap_is_disabled())
159 return;
160
Christophe Leroyba454f92021-10-19 09:29:20 +0200161 __restore_user_access(flags);
162}
163#endif /* CONFIG_PPC_BOOK3S_64 */
164
Christophe Leroy240efd72021-06-03 09:13:54 +0000165static __always_inline void allow_read_from_user(const void __user *from, unsigned long size)
Christophe Leroyde78a9c2019-04-18 16:51:20 +1000166{
Christophe Leroy8524e2e2021-02-07 10:08:11 +0000167 barrier_nospec();
Christophe Leroy1d8f7392020-01-24 11:54:41 +0000168 allow_user_access(NULL, from, size, KUAP_READ);
Christophe Leroyde78a9c2019-04-18 16:51:20 +1000169}
170
Christophe Leroy240efd72021-06-03 09:13:54 +0000171static __always_inline void allow_write_to_user(void __user *to, unsigned long size)
Christophe Leroyde78a9c2019-04-18 16:51:20 +1000172{
Christophe Leroy1d8f7392020-01-24 11:54:41 +0000173 allow_user_access(to, NULL, size, KUAP_WRITE);
174}
175
Christophe Leroy240efd72021-06-03 09:13:54 +0000176static __always_inline void allow_read_write_user(void __user *to, const void __user *from,
177 unsigned long size)
Christophe Leroy1d8f7392020-01-24 11:54:41 +0000178{
Christophe Leroy8524e2e2021-02-07 10:08:11 +0000179 barrier_nospec();
Christophe Leroy1d8f7392020-01-24 11:54:41 +0000180 allow_user_access(to, from, size, KUAP_READ_WRITE);
Christophe Leroyde78a9c2019-04-18 16:51:20 +1000181}
182
Christophe Leroy240efd72021-06-03 09:13:54 +0000183static __always_inline void prevent_read_from_user(const void __user *from, unsigned long size)
Christophe Leroyde78a9c2019-04-18 16:51:20 +1000184{
Christophe Leroycb2f1fb2021-06-03 08:41:48 +0000185 prevent_user_access(KUAP_READ);
Christophe Leroyde78a9c2019-04-18 16:51:20 +1000186}
187
Christophe Leroy240efd72021-06-03 09:13:54 +0000188static __always_inline void prevent_write_to_user(void __user *to, unsigned long size)
Christophe Leroyde78a9c2019-04-18 16:51:20 +1000189{
Christophe Leroycb2f1fb2021-06-03 08:41:48 +0000190 prevent_user_access(KUAP_WRITE);
Christophe Leroy1d8f7392020-01-24 11:54:41 +0000191}
192
Christophe Leroy240efd72021-06-03 09:13:54 +0000193static __always_inline void prevent_read_write_user(void __user *to, const void __user *from,
194 unsigned long size)
Christophe Leroy1d8f7392020-01-24 11:54:41 +0000195{
Christophe Leroycb2f1fb2021-06-03 08:41:48 +0000196 prevent_user_access(KUAP_READ_WRITE);
Christophe Leroyde78a9c2019-04-18 16:51:20 +1000197}
198
Christophe Leroy240efd72021-06-03 09:13:54 +0000199static __always_inline void prevent_current_access_user(void)
Christophe Leroybedb4db2020-01-24 11:54:43 +0000200{
Christophe Leroycb2f1fb2021-06-03 08:41:48 +0000201 prevent_user_access(KUAP_READ_WRITE);
Christophe Leroybedb4db2020-01-24 11:54:43 +0000202}
203
Christophe Leroy240efd72021-06-03 09:13:54 +0000204static __always_inline void prevent_current_read_from_user(void)
Christophe Leroy4fe5cda2020-04-03 07:20:53 +0000205{
Christophe Leroycb2f1fb2021-06-03 08:41:48 +0000206 prevent_user_access(KUAP_READ);
Christophe Leroy4fe5cda2020-04-03 07:20:53 +0000207}
208
Christophe Leroy240efd72021-06-03 09:13:54 +0000209static __always_inline void prevent_current_write_to_user(void)
Christophe Leroy4fe5cda2020-04-03 07:20:53 +0000210{
Christophe Leroycb2f1fb2021-06-03 08:41:48 +0000211 prevent_user_access(KUAP_WRITE);
Christophe Leroy4fe5cda2020-04-03 07:20:53 +0000212}
213
Christophe Leroy69795ca2019-04-18 16:51:18 +1000214#endif /* !__ASSEMBLY__ */
215
Christophe Leroy1d8f7392020-01-24 11:54:41 +0000216#endif /* _ASM_POWERPC_KUAP_H_ */