gcs.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (C) 2023 ARM Ltd.
  4. */
  5. #ifndef __ASM_GCS_H
  6. #define __ASM_GCS_H
  7. #include <asm/types.h>
  8. #include <asm/uaccess.h>
  9. struct kernel_clone_args;
  10. struct ksignal;
  11. static inline void gcsb_dsync(void)
  12. {
  13. asm volatile(".inst 0xd503227f" : : : "memory");
  14. }
  15. static inline void gcsstr(u64 *addr, u64 val)
  16. {
  17. register u64 *_addr __asm__ ("x0") = addr;
  18. register long _val __asm__ ("x1") = val;
  19. /* GCSSTTR x1, [x0] */
  20. asm volatile(
  21. ".inst 0xd91f1c01\n"
  22. :
  23. : "rZ" (_val), "r" (_addr)
  24. : "memory");
  25. }
  26. static inline void gcsss1(u64 Xt)
  27. {
  28. asm volatile (
  29. "sys #3, C7, C7, #2, %0\n"
  30. :
  31. : "rZ" (Xt)
  32. : "memory");
  33. }
  34. static inline u64 gcsss2(void)
  35. {
  36. u64 Xt;
  37. asm volatile(
  38. "SYSL %0, #3, C7, C7, #3\n"
  39. : "=r" (Xt)
  40. :
  41. : "memory");
  42. return Xt;
  43. }
  44. #define PR_SHADOW_STACK_SUPPORTED_STATUS_MASK \
  45. (PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | PR_SHADOW_STACK_PUSH)
  46. #ifdef CONFIG_ARM64_GCS
  47. static inline bool task_gcs_el0_enabled(struct task_struct *task)
  48. {
  49. return task->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE;
  50. }
  51. void gcs_set_el0_mode(struct task_struct *task);
  52. void gcs_free(struct task_struct *task);
  53. void gcs_preserve_current_state(void);
  54. unsigned long gcs_alloc_thread_stack(struct task_struct *tsk,
  55. const struct kernel_clone_args *args);
  56. static inline int gcs_check_locked(struct task_struct *task,
  57. unsigned long new_val)
  58. {
  59. unsigned long cur_val = task->thread.gcs_el0_mode;
  60. cur_val &= task->thread.gcs_el0_locked;
  61. new_val &= task->thread.gcs_el0_locked;
  62. if (cur_val != new_val)
  63. return -EBUSY;
  64. return 0;
  65. }
  66. static inline int gcssttr(unsigned long __user *addr, unsigned long val)
  67. {
  68. register unsigned long __user *_addr __asm__ ("x0") = addr;
  69. register unsigned long _val __asm__ ("x1") = val;
  70. int err = 0;
  71. /* GCSSTTR x1, [x0] */
  72. asm volatile(
  73. "1: .inst 0xd91f1c01\n"
  74. "2: \n"
  75. _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %w0)
  76. : "+r" (err)
  77. : "rZ" (_val), "r" (_addr)
  78. : "memory");
  79. return err;
  80. }
  81. static inline void put_user_gcs(unsigned long val, unsigned long __user *addr,
  82. int *err)
  83. {
  84. int ret;
  85. if (!access_ok((char __user *)addr, sizeof(u64))) {
  86. *err = -EFAULT;
  87. return;
  88. }
  89. uaccess_ttbr0_enable();
  90. ret = gcssttr(addr, val);
  91. if (ret != 0)
  92. *err = ret;
  93. uaccess_ttbr0_disable();
  94. }
  95. static inline void push_user_gcs(unsigned long val, int *err)
  96. {
  97. u64 gcspr = read_sysreg_s(SYS_GCSPR_EL0);
  98. gcspr -= sizeof(u64);
  99. put_user_gcs(val, (unsigned long __user *)gcspr, err);
  100. if (!*err)
  101. write_sysreg_s(gcspr, SYS_GCSPR_EL0);
  102. }
  103. /*
  104. * Unlike put/push_user_gcs() above, get/pop_user_gsc() doesn't
  105. * validate the GCS permission is set on the page being read. This
  106. * differs from how the hardware works when it consumes data stored at
  107. * GCSPR. Callers should ensure this is acceptable.
  108. */
  109. static inline u64 get_user_gcs(unsigned long __user *addr, int *err)
  110. {
  111. unsigned long ret;
  112. u64 load = 0;
  113. /* Ensure previous GCS operation are visible before we read the page */
  114. gcsb_dsync();
  115. ret = copy_from_user(&load, addr, sizeof(load));
  116. if (ret != 0)
  117. *err = ret;
  118. return load;
  119. }
  120. static inline u64 pop_user_gcs(int *err)
  121. {
  122. u64 gcspr = read_sysreg_s(SYS_GCSPR_EL0);
  123. u64 read_val;
  124. read_val = get_user_gcs((__force unsigned long __user *)gcspr, err);
  125. if (!*err)
  126. write_sysreg_s(gcspr + sizeof(u64), SYS_GCSPR_EL0);
  127. return read_val;
  128. }
  129. #else
  130. static inline bool task_gcs_el0_enabled(struct task_struct *task)
  131. {
  132. return false;
  133. }
  134. static inline void gcs_set_el0_mode(struct task_struct *task) { }
  135. static inline void gcs_free(struct task_struct *task) { }
  136. static inline void gcs_preserve_current_state(void) { }
  137. static inline void put_user_gcs(unsigned long val, unsigned long __user *addr,
  138. int *err) { }
  139. static inline void push_user_gcs(unsigned long val, int *err) { }
  140. static inline unsigned long gcs_alloc_thread_stack(struct task_struct *tsk,
  141. const struct kernel_clone_args *args)
  142. {
  143. return -ENOTSUPP;
  144. }
  145. static inline int gcs_check_locked(struct task_struct *task,
  146. unsigned long new_val)
  147. {
  148. return 0;
  149. }
  150. static inline u64 get_user_gcs(unsigned long __user *addr, int *err)
  151. {
  152. *err = -EFAULT;
  153. return 0;
  154. }
  155. static inline u64 pop_user_gcs(int *err)
  156. {
  157. return 0;
  158. }
  159. #endif
  160. #endif