vector.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2023 SiFive
  4. * Author: Andy Chiu <andy.chiu@sifive.com>
  5. */
  6. #include <linux/export.h>
  7. #include <linux/sched/signal.h>
  8. #include <linux/types.h>
  9. #include <linux/slab.h>
  10. #include <linux/sched.h>
  11. #include <linux/uaccess.h>
  12. #include <linux/prctl.h>
  13. #include <asm/thread_info.h>
  14. #include <asm/processor.h>
  15. #include <asm/insn.h>
  16. #include <asm/vector.h>
  17. #include <asm/csr.h>
  18. #include <asm/elf.h>
  19. #include <asm/ptrace.h>
  20. #include <asm/bug.h>
  21. static bool riscv_v_implicit_uacc = IS_ENABLED(CONFIG_RISCV_ISA_V_DEFAULT_ENABLE);
  22. static struct kmem_cache *riscv_v_user_cachep;
  23. #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE
  24. static struct kmem_cache *riscv_v_kernel_cachep;
  25. #endif
  26. unsigned long riscv_v_vsize __read_mostly;
  27. EXPORT_SYMBOL_GPL(riscv_v_vsize);
  28. int riscv_v_setup_vsize(void)
  29. {
  30. unsigned long this_vsize;
  31. /* There are 32 vector registers with vlenb length. */
  32. riscv_v_enable();
  33. this_vsize = csr_read(CSR_VLENB) * 32;
  34. riscv_v_disable();
  35. if (!riscv_v_vsize) {
  36. riscv_v_vsize = this_vsize;
  37. return 0;
  38. }
  39. if (riscv_v_vsize != this_vsize) {
  40. WARN(1, "RISCV_ISA_V only supports one vlenb on SMP systems");
  41. return -EOPNOTSUPP;
  42. }
  43. return 0;
  44. }
  45. void __init riscv_v_setup_ctx_cache(void)
  46. {
  47. if (!has_vector())
  48. return;
  49. riscv_v_user_cachep = kmem_cache_create_usercopy("riscv_vector_ctx",
  50. riscv_v_vsize, 16, SLAB_PANIC,
  51. 0, riscv_v_vsize, NULL);
  52. #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE
  53. riscv_v_kernel_cachep = kmem_cache_create("riscv_vector_kctx",
  54. riscv_v_vsize, 16,
  55. SLAB_PANIC, NULL);
  56. #endif
  57. }
  58. static bool insn_is_vector(u32 insn_buf)
  59. {
  60. u32 opcode = insn_buf & __INSN_OPCODE_MASK;
  61. u32 width, csr;
  62. /*
  63. * All V-related instructions, including CSR operations are 4-Byte. So,
  64. * do not handle if the instruction length is not 4-Byte.
  65. */
  66. if (unlikely(GET_INSN_LENGTH(insn_buf) != 4))
  67. return false;
  68. switch (opcode) {
  69. case RVV_OPCODE_VECTOR:
  70. return true;
  71. case RVV_OPCODE_VL:
  72. case RVV_OPCODE_VS:
  73. width = RVV_EXRACT_VL_VS_WIDTH(insn_buf);
  74. if (width == RVV_VL_VS_WIDTH_8 || width == RVV_VL_VS_WIDTH_16 ||
  75. width == RVV_VL_VS_WIDTH_32 || width == RVV_VL_VS_WIDTH_64)
  76. return true;
  77. break;
  78. case RVG_OPCODE_SYSTEM:
  79. csr = RVG_EXTRACT_SYSTEM_CSR(insn_buf);
  80. if ((csr >= CSR_VSTART && csr <= CSR_VCSR) ||
  81. (csr >= CSR_VL && csr <= CSR_VLENB))
  82. return true;
  83. }
  84. return false;
  85. }
  86. static int riscv_v_thread_zalloc(struct kmem_cache *cache,
  87. struct __riscv_v_ext_state *ctx)
  88. {
  89. void *datap;
  90. datap = kmem_cache_zalloc(cache, GFP_KERNEL);
  91. if (!datap)
  92. return -ENOMEM;
  93. ctx->datap = datap;
  94. memset(ctx, 0, offsetof(struct __riscv_v_ext_state, datap));
  95. return 0;
  96. }
  97. void riscv_v_thread_alloc(struct task_struct *tsk)
  98. {
  99. #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE
  100. riscv_v_thread_zalloc(riscv_v_kernel_cachep, &tsk->thread.kernel_vstate);
  101. #endif
  102. }
  103. void riscv_v_thread_free(struct task_struct *tsk)
  104. {
  105. if (tsk->thread.vstate.datap)
  106. kmem_cache_free(riscv_v_user_cachep, tsk->thread.vstate.datap);
  107. #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE
  108. if (tsk->thread.kernel_vstate.datap)
  109. kmem_cache_free(riscv_v_kernel_cachep, tsk->thread.kernel_vstate.datap);
  110. #endif
  111. }
  112. #define VSTATE_CTRL_GET_CUR(x) ((x) & PR_RISCV_V_VSTATE_CTRL_CUR_MASK)
  113. #define VSTATE_CTRL_GET_NEXT(x) (((x) & PR_RISCV_V_VSTATE_CTRL_NEXT_MASK) >> 2)
  114. #define VSTATE_CTRL_MAKE_NEXT(x) (((x) << 2) & PR_RISCV_V_VSTATE_CTRL_NEXT_MASK)
  115. #define VSTATE_CTRL_GET_INHERIT(x) (!!((x) & PR_RISCV_V_VSTATE_CTRL_INHERIT))
  116. static inline int riscv_v_ctrl_get_cur(struct task_struct *tsk)
  117. {
  118. return VSTATE_CTRL_GET_CUR(tsk->thread.vstate_ctrl);
  119. }
  120. static inline int riscv_v_ctrl_get_next(struct task_struct *tsk)
  121. {
  122. return VSTATE_CTRL_GET_NEXT(tsk->thread.vstate_ctrl);
  123. }
  124. static inline bool riscv_v_ctrl_test_inherit(struct task_struct *tsk)
  125. {
  126. return VSTATE_CTRL_GET_INHERIT(tsk->thread.vstate_ctrl);
  127. }
  128. static inline void riscv_v_ctrl_set(struct task_struct *tsk, int cur, int nxt,
  129. bool inherit)
  130. {
  131. unsigned long ctrl;
  132. ctrl = cur & PR_RISCV_V_VSTATE_CTRL_CUR_MASK;
  133. ctrl |= VSTATE_CTRL_MAKE_NEXT(nxt);
  134. if (inherit)
  135. ctrl |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
  136. tsk->thread.vstate_ctrl &= ~PR_RISCV_V_VSTATE_CTRL_MASK;
  137. tsk->thread.vstate_ctrl |= ctrl;
  138. }
  139. bool riscv_v_vstate_ctrl_user_allowed(void)
  140. {
  141. return riscv_v_ctrl_get_cur(current) == PR_RISCV_V_VSTATE_CTRL_ON;
  142. }
  143. EXPORT_SYMBOL_GPL(riscv_v_vstate_ctrl_user_allowed);
  144. bool riscv_v_first_use_handler(struct pt_regs *regs)
  145. {
  146. u32 __user *epc = (u32 __user *)regs->epc;
  147. u32 insn = (u32)regs->badaddr;
  148. if (!has_vector())
  149. return false;
  150. /* Do not handle if V is not supported, or disabled */
  151. if (!riscv_v_vstate_ctrl_user_allowed())
  152. return false;
  153. /* If V has been enabled then it is not the first-use trap */
  154. if (riscv_v_vstate_query(regs))
  155. return false;
  156. /* Get the instruction */
  157. if (!insn) {
  158. if (__get_user(insn, epc))
  159. return false;
  160. }
  161. /* Filter out non-V instructions */
  162. if (!insn_is_vector(insn))
  163. return false;
  164. /* Sanity check. datap should be null by the time of the first-use trap */
  165. WARN_ON(current->thread.vstate.datap);
  166. /*
  167. * Now we sure that this is a V instruction. And it executes in the
  168. * context where VS has been off. So, try to allocate the user's V
  169. * context and resume execution.
  170. */
  171. if (riscv_v_thread_zalloc(riscv_v_user_cachep, &current->thread.vstate)) {
  172. force_sig(SIGBUS);
  173. return true;
  174. }
  175. riscv_v_vstate_on(regs);
  176. riscv_v_vstate_set_restore(current, regs);
  177. return true;
  178. }
  179. void riscv_v_vstate_ctrl_init(struct task_struct *tsk)
  180. {
  181. bool inherit;
  182. int cur, next;
  183. if (!has_vector())
  184. return;
  185. next = riscv_v_ctrl_get_next(tsk);
  186. if (!next) {
  187. if (READ_ONCE(riscv_v_implicit_uacc))
  188. cur = PR_RISCV_V_VSTATE_CTRL_ON;
  189. else
  190. cur = PR_RISCV_V_VSTATE_CTRL_OFF;
  191. } else {
  192. cur = next;
  193. }
  194. /* Clear next mask if inherit-bit is not set */
  195. inherit = riscv_v_ctrl_test_inherit(tsk);
  196. if (!inherit)
  197. next = PR_RISCV_V_VSTATE_CTRL_DEFAULT;
  198. riscv_v_ctrl_set(tsk, cur, next, inherit);
  199. }
  200. long riscv_v_vstate_ctrl_get_current(void)
  201. {
  202. if (!has_vector())
  203. return -EINVAL;
  204. return current->thread.vstate_ctrl & PR_RISCV_V_VSTATE_CTRL_MASK;
  205. }
  206. long riscv_v_vstate_ctrl_set_current(unsigned long arg)
  207. {
  208. bool inherit;
  209. int cur, next;
  210. if (!has_vector())
  211. return -EINVAL;
  212. if (arg & ~PR_RISCV_V_VSTATE_CTRL_MASK)
  213. return -EINVAL;
  214. cur = VSTATE_CTRL_GET_CUR(arg);
  215. switch (cur) {
  216. case PR_RISCV_V_VSTATE_CTRL_OFF:
  217. /* Do not allow user to turn off V if current is not off */
  218. if (riscv_v_ctrl_get_cur(current) != PR_RISCV_V_VSTATE_CTRL_OFF)
  219. return -EPERM;
  220. break;
  221. case PR_RISCV_V_VSTATE_CTRL_ON:
  222. break;
  223. case PR_RISCV_V_VSTATE_CTRL_DEFAULT:
  224. cur = riscv_v_ctrl_get_cur(current);
  225. break;
  226. default:
  227. return -EINVAL;
  228. }
  229. next = VSTATE_CTRL_GET_NEXT(arg);
  230. inherit = VSTATE_CTRL_GET_INHERIT(arg);
  231. switch (next) {
  232. case PR_RISCV_V_VSTATE_CTRL_DEFAULT:
  233. case PR_RISCV_V_VSTATE_CTRL_OFF:
  234. case PR_RISCV_V_VSTATE_CTRL_ON:
  235. riscv_v_ctrl_set(current, cur, next, inherit);
  236. return 0;
  237. }
  238. return -EINVAL;
  239. }
  240. #ifdef CONFIG_SYSCTL
  241. static struct ctl_table riscv_v_default_vstate_table[] = {
  242. {
  243. .procname = "riscv_v_default_allow",
  244. .data = &riscv_v_implicit_uacc,
  245. .maxlen = sizeof(riscv_v_implicit_uacc),
  246. .mode = 0644,
  247. .proc_handler = proc_dobool,
  248. },
  249. };
  250. static int __init riscv_v_sysctl_init(void)
  251. {
  252. if (has_vector())
  253. if (!register_sysctl("abi", riscv_v_default_vstate_table))
  254. return -EINVAL;
  255. return 0;
  256. }
  257. #else /* ! CONFIG_SYSCTL */
  258. static int __init riscv_v_sysctl_init(void) { return 0; }
  259. #endif /* ! CONFIG_SYSCTL */
  260. static int __init riscv_v_init(void)
  261. {
  262. return riscv_v_sysctl_init();
  263. }
  264. core_initcall(riscv_v_init);