ipc.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * Copyright (c) 2022 Agustina Arzille.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. * Definitions for inter-process communication.
  18. */
  19. #ifndef KERN_IPC_H
  20. #define KERN_IPC_H
  21. #include <iovec.h>
  22. #include <stdbool.h>
  23. #include <stdint.h>
  24. #include <kern/types.h>
  25. struct ipc_msg_vme
  26. {
  27. uintptr_t addr;
  28. size_t size;
  29. int prot;
  30. int max_prot;
  31. };
  32. struct ipc_msg_cap
  33. {
  34. int cap;
  35. int flags;
  36. };
  37. #define IPC_IOV_ITER_CACHE_SIZE 8
  38. struct ipc_iov_iter
  39. {
  40. struct iovec cache[IPC_IOV_ITER_CACHE_SIZE];
  41. uint32_t cache_idx;
  42. struct iovec head;
  43. struct iovec *begin;
  44. uint32_t cur;
  45. uint32_t end;
  46. };
  47. struct ipc_cap_iter
  48. {
  49. struct ipc_msg_cap *begin;
  50. uint32_t cur;
  51. uint32_t end;
  52. };
  53. struct ipc_vme_iter
  54. {
  55. struct ipc_msg_vme *begin;
  56. uint32_t cur;
  57. uint32_t end;
  58. };
  59. struct ipc_msg
  60. {
  61. size_t size;
  62. struct iovec *iovs;
  63. uint32_t iov_cnt;
  64. struct ipc_msg_vme *vmes;
  65. uint32_t vme_cnt;
  66. struct ipc_msg_cap *caps;
  67. uint32_t cap_cnt;
  68. };
  69. // Bits for the 'flags' member of a IPC message metadata.
  70. #define IPC_MSG_TRUNC 0x01 // Reply was truncated.
  71. #define IPC_MSG_ERROR 0x02 // There was an error during IPC.
  72. struct ipc_msg_data
  73. {
  74. size_t size;
  75. int task_id;
  76. int thread_id;
  77. uint32_t flags;
  78. uintptr_t tag;
  79. ssize_t bytes_sent;
  80. uint32_t vmes_sent;
  81. uint32_t caps_sent;
  82. ssize_t bytes_recv;
  83. uint32_t vmes_recv;
  84. uint32_t caps_recv;
  85. };
  86. struct task;
  87. // Direction of the binary copy, relative to the remote task.
  88. #define IPC_COPY_FROM 0
  89. #define IPC_COPY_TO 1
  90. /*
  91. * IPC iterator functions.
  92. *
  93. * These come in 3 flavors: iovec, capabilities and VMEs. The former works
  94. * by simply copying data; the other 2 by transfering objects across tasks.
  95. */
  96. static inline void
  97. ipc_cap_iter_init (struct ipc_cap_iter *it,
  98. struct ipc_msg_cap *msg, uint32_t nr_msgs)
  99. {
  100. it->begin = msg;
  101. it->cur = 0, it->end = nr_msgs;
  102. }
  103. static inline int
  104. ipc_cap_iter_size (const struct ipc_cap_iter *it)
  105. {
  106. return ((int)(it->end - it->cur));
  107. }
  108. static inline void
  109. ipc_vme_iter_init (struct ipc_vme_iter *it,
  110. struct ipc_msg_vme *msg, uint32_t nr_msgs)
  111. {
  112. it->begin = msg;
  113. it->cur = 0, it->end = nr_msgs;
  114. }
  115. static inline int
  116. ipc_vme_iter_size (const struct ipc_vme_iter *it)
  117. {
  118. return ((int)(it->end - it->cur));
  119. }
  120. static inline void
  121. ipc_iov_iter_init_buf (struct ipc_iov_iter *it, void *buf, size_t size)
  122. {
  123. it->head = IOVEC (buf, size);
  124. it->cache_idx = IPC_IOV_ITER_CACHE_SIZE;
  125. it->begin = &it->head;
  126. it->cur = it->end = 1;
  127. }
  128. static inline bool
  129. ipc_iov_iter_empty (const struct ipc_iov_iter *it)
  130. {
  131. return (it->cur >= it->end && !it->head.iov_len &&
  132. it->cache_idx >= IPC_IOV_ITER_CACHE_SIZE);
  133. }
  134. static inline void
  135. ipc_iov_iter_init (struct ipc_iov_iter *it, struct iovec *vecs, uint32_t cnt)
  136. {
  137. it->head.iov_len = 0;
  138. it->begin = vecs;
  139. it->cur = 0, it->end = cnt;
  140. it->cache_idx = IPC_IOV_ITER_CACHE_SIZE;
  141. }
  142. // Copy bytes between a local and a remote task.
  143. ssize_t ipc_bcopy (struct task *r_task, void *r_ptr, size_t r_size,
  144. void *l_ptr, size_t l_size, int direction);
  145. // Copy bytes in iterators between a local and a remote task.
  146. ssize_t ipc_iov_iter_copy (struct task *r_task, struct ipc_iov_iter *r_it,
  147. struct ipc_iov_iter *l_it, int direction);
  148. // Transfer capabilities in iterators between a local and a remote task.
  149. int ipc_cap_iter_copy (struct task *r_task, struct ipc_cap_iter *r_it,
  150. struct ipc_cap_iter *l_it, int direction);
  151. // Transfer VMEs in iterators between a local and a remote task.
  152. int ipc_vme_iter_copy (struct task *r_task, struct ipc_vme_iter *r_it,
  153. struct ipc_vme_iter *l_it, int direction);
  154. // Copy bytes in iovecs between a local and a remote task.
  155. static inline ssize_t
  156. ipc_bcopyv (struct task *r_task, struct iovec *r_iov, uint32_t r_niov,
  157. struct iovec *l_iov, uint32_t l_niov, int direction)
  158. {
  159. struct ipc_iov_iter r_it, l_it;
  160. ipc_iov_iter_init (&l_it, l_iov, l_niov);
  161. ipc_iov_iter_init (&r_it, r_iov, r_niov);
  162. return (ipc_iov_iter_copy (r_task, &r_it, &l_it, direction));
  163. }
  164. // Transfer VMEs between a remote and a local task.
  165. static inline int
  166. ipc_copy_vmes (struct task *r_task, struct ipc_msg_vme *r_vmes,
  167. uint32_t r_nvmes, struct ipc_msg_vme *l_vmes,
  168. uint32_t l_nvmes, int direction)
  169. {
  170. struct ipc_vme_iter r_it, l_it;
  171. ipc_vme_iter_init (&r_it, r_vmes, r_nvmes);
  172. ipc_vme_iter_init (&l_it, l_vmes, l_nvmes);
  173. return (ipc_vme_iter_copy (r_task, &r_it, &l_it, direction));
  174. }
  175. // Transfer capabilities between a remote and a local task.
  176. static inline int
  177. ipc_copy_caps (struct task *r_task, struct ipc_msg_cap *r_caps,
  178. uint32_t r_ncaps, struct ipc_msg_cap *l_caps,
  179. uint32_t l_ncaps, int direction)
  180. {
  181. struct ipc_cap_iter r_it, l_it;
  182. ipc_cap_iter_init (&r_it, r_caps, r_ncaps);
  183. ipc_cap_iter_init (&l_it, l_caps, l_ncaps);
  184. return (ipc_cap_iter_copy (r_task, &r_it, &l_it, direction));
  185. }
  186. #endif