File Index
Files and directories
Sign in
FILE

kup.h

File preview with syntax highlighting.

linux-6.19.14/arch/powerpc/include/asm/kup.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  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#ifndef __ASSEMBLER__
 10#include <linux/types.h>
 11
 12static __always_inline bool kuap_is_disabled(void);
 13#endif
 14
 15#ifdef CONFIG_PPC_BOOK3S_64
 16#include <asm/book3s/64/kup.h>
 17#endif
 18
 19#ifdef CONFIG_PPC_8xx
 20#include <asm/nohash/32/kup-8xx.h>
 21#endif
 22
 23#ifdef CONFIG_BOOKE
 24#include <asm/nohash/kup-booke.h>
 25#endif
 26
 27#ifdef CONFIG_PPC_BOOK3S_32
 28#include <asm/book3s/32/kup.h>
 29#endif
 30
 31#ifdef __ASSEMBLER__
 32#ifndef CONFIG_PPC_KUAP
 33.macro kuap_check_amr	gpr1, gpr2
 34.endm
 35
 36#endif
 37
 38#else /* !__ASSEMBLER__ */
 39
 40extern bool disable_kuep;
 41extern bool disable_kuap;
 42
 43#include <linux/pgtable.h>
 44
 45void setup_kup(void);
 46void setup_kuep(bool disabled);
 47
 48#ifdef CONFIG_PPC_KUAP
 49void setup_kuap(bool disabled);
 50
 51static __always_inline bool kuap_is_disabled(void)
 52{
 53	return !mmu_has_feature(MMU_FTR_KUAP);
 54}
 55#else
 56static inline void setup_kuap(bool disabled) { }
 57
 58static __always_inline bool kuap_is_disabled(void) { return true; }
 59
 60static __always_inline bool
 61__bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
 62{
 63	return false;
 64}
 65
 66static __always_inline void kuap_user_restore(struct pt_regs *regs) { }
 67static __always_inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) { }
 68
 69/*
 70 * book3s/64/kup-radix.h defines these functions for the !KUAP case to flush
 71 * the L1D cache after user accesses. Only include the empty stubs for other
 72 * platforms.
 73 */
 74#ifndef CONFIG_PPC_BOOK3S_64
 75static __always_inline void allow_user_access(void __user *to, const void __user *from,
 76					      unsigned long size, unsigned long dir) { }
 77static __always_inline void prevent_user_access(unsigned long dir) { }
 78static __always_inline unsigned long prevent_user_access_return(void) { return 0UL; }
 79static __always_inline void restore_user_access(unsigned long flags) { }
 80#endif /* CONFIG_PPC_BOOK3S_64 */
 81#endif /* CONFIG_PPC_KUAP */
 82
 83static __always_inline bool
 84bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
 85{
 86	if (kuap_is_disabled())
 87		return false;
 88
 89	return __bad_kuap_fault(regs, address, is_write);
 90}
 91
 92static __always_inline void kuap_lock(void)
 93{
 94#ifdef __kuap_lock
 95	if (kuap_is_disabled())
 96		return;
 97
 98	__kuap_lock();
 99#endif
100}
101
102static __always_inline void kuap_save_and_lock(struct pt_regs *regs)
103{
104#ifdef __kuap_save_and_lock
105	if (kuap_is_disabled())
106		return;
107
108	__kuap_save_and_lock(regs);
109#endif
110}
111
112static __always_inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long amr)
113{
114	if (kuap_is_disabled())
115		return;
116
117	__kuap_kernel_restore(regs, amr);
118}
119
120static __always_inline unsigned long kuap_get_and_assert_locked(void)
121{
122#ifdef __kuap_get_and_assert_locked
123	if (!kuap_is_disabled())
124		return __kuap_get_and_assert_locked();
125#endif
126	return 0;
127}
128
129static __always_inline void kuap_assert_locked(void)
130{
131	if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG))
132		kuap_get_and_assert_locked();
133}
134
135static __always_inline void allow_read_from_user(const void __user *from, unsigned long size)
136{
137	allow_user_access(NULL, from, size, KUAP_READ);
138}
139
140static __always_inline void allow_write_to_user(void __user *to, unsigned long size)
141{
142	allow_user_access(to, NULL, size, KUAP_WRITE);
143}
144
145static __always_inline void allow_read_write_user(void __user *to, const void __user *from,
146						  unsigned long size)
147{
148	allow_user_access(to, from, size, KUAP_READ_WRITE);
149}
150
151static __always_inline void prevent_read_from_user(const void __user *from, unsigned long size)
152{
153	prevent_user_access(KUAP_READ);
154}
155
156static __always_inline void prevent_write_to_user(void __user *to, unsigned long size)
157{
158	prevent_user_access(KUAP_WRITE);
159}
160
161static __always_inline void prevent_read_write_user(void __user *to, const void __user *from,
162						    unsigned long size)
163{
164	prevent_user_access(KUAP_READ_WRITE);
165}
166
167static __always_inline void prevent_current_access_user(void)
168{
169	prevent_user_access(KUAP_READ_WRITE);
170}
171
172static __always_inline void prevent_current_read_from_user(void)
173{
174	prevent_user_access(KUAP_READ);
175}
176
177static __always_inline void prevent_current_write_to_user(void)
178{
179	prevent_user_access(KUAP_WRITE);
180}
181
182#endif /* !__ASSEMBLER__ */
183
184#endif /* _ASM_POWERPC_KUAP_H_ */
~/ Read-only file preview.