kup.h 4.8 KB

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