mem-buf-msgq.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #ifndef MEM_BUF_MSGQ_H
  7. #define MEM_BUF_MSGQ_H
  8. #include <linux/mem-buf.h>
  9. #include <linux/types.h>
  10. /**
  11. * enum mem_buf_msg_type: Message types used by the membuf driver for
  12. * communication.
  13. * @MEM_BUF_ALLOC_REQ: The message is an allocation request from another VM to
  14. * the receiving VM
  15. * @MEM_BUF_ALLOC_RESP: The message is a response from a remote VM to an
  16. * allocation request issued by the receiving VM
  17. * @MEM_BUF_ALLOC_RELINQUISH: The message is a notification from another VM
  18. * that the receiving VM can reclaim the memory.
  19. * @MEM_BUF_ALLOC_RELINQUISH_RESP: Indicates completion of MEM_BUF_ALLOC_RELINQUISH.
  20. */
  21. enum mem_buf_msg_type {
  22. MEM_BUF_ALLOC_REQ,
  23. MEM_BUF_ALLOC_RESP,
  24. MEM_BUF_ALLOC_RELINQUISH,
  25. MEM_BUF_ALLOC_RELINQUISH_RESP,
  26. MEM_BUF_ALLOC_REQ_MAX,
  27. };
  28. /**
  29. * struct mem_buf_msg_hdr: The header for all membuf messages
  30. * @txn_id: The transaction ID for the message. This field is only meaningful
  31. * for request/response type of messages.
  32. * @msg_type: The type of message.
  33. * @msg_size: The size of message.
  34. */
  35. struct mem_buf_msg_hdr {
  36. u32 txn_id;
  37. u32 msg_type;
  38. u32 msg_size;
  39. } __packed;
  40. /**
  41. * struct mem_buf_alloc_req: The message format for a memory allocation request
  42. * to another VM.
  43. * @hdr: Message header
  44. * @size: The size of the memory allocation to be performed on the remote VM.
  45. * @src_mem_type: The type of memory that the remote VM should allocate.
  46. * @trans_type: One of GH_RM_TRANS_TYPE_DONATE/SHARE/LEND
  47. * @acl_desc: A GH ACL descriptor that describes the VMIDs that will be
  48. * accessing the memory, as well as what permissions each VMID will have.
  49. *
  50. * NOTE: Certain memory types require additional information for the remote VM
  51. * to interpret. That information should be concatenated with this structure
  52. * prior to sending the allocation request to the remote VM. For example,
  53. * with memory type DMAHEAP, the allocation request message will consist of this
  54. * structure, as well as the name of the heap that will source the allocation.
  55. */
  56. struct mem_buf_alloc_req {
  57. struct mem_buf_msg_hdr hdr;
  58. u64 size;
  59. u32 src_mem_type;
  60. u32 trans_type;
  61. struct gh_acl_desc acl_desc;
  62. } __packed;
  63. /**
  64. * struct mem_buf_alloc_resp: The message format for a memory allocation
  65. * request response.
  66. * @hdr: Message header
  67. * @ret: Return code from remote VM
  68. * @hdl: The memparcel handle associated with the memory allocated to the
  69. * receiving VM. This field is only meaningful if the allocation on the remote
  70. * VM was carried out successfully, as denoted by @ret.
  71. * (i.e. memory donation, sharing, or lending).
  72. * @obj_id: Unique identifier for the memory object associated with handle.
  73. */
  74. struct mem_buf_alloc_resp {
  75. struct mem_buf_msg_hdr hdr;
  76. s32 ret;
  77. u32 hdl;
  78. u32 obj_id;
  79. } __packed;
  80. /**
  81. * struct mem_buf_alloc_relinquish: The message format for a notification
  82. * that the current VM has relinquished access to the memory lent to it by
  83. * another VM.
  84. * @hdr: Message header
  85. * @hdl: The memparcel handle associated with the memory.
  86. * @obj_id: Unique identifier for the memory object associated with handle.
  87. */
  88. struct mem_buf_alloc_relinquish {
  89. struct mem_buf_msg_hdr hdr;
  90. u32 hdl;
  91. u32 obj_id;
  92. } __packed;
  93. /*
  94. * mem_buf_msgq_ops: A set of ops that are invoked when a message of particular
  95. * types are received by a mem-buf message queue.
  96. *
  97. * The handlers are responsible for freeing the msg buffer that is passed to
  98. * them.
  99. *
  100. * @alloc_req_hdlr: The handler for messages of type MEM_BUF_ALLOC_REQ.
  101. * @alloc_resp_hdlr: The handler for messages of type MEM_BUF_ALLOC_RESP.
  102. * @relinquish_hdlr: The handler for messages of type MEM_BUF_ALLOC_RELINQUISH.
  103. * @relinquish_memparcel_hdl: Callback for relinquishing a memparcel. This is typically used in
  104. * case an allocation request times out, and the response arrives late.
  105. * In this case, the transaction will have been aborted, but the memory
  106. * still needs to be relinquished.
  107. */
  108. struct mem_buf_msgq_ops {
  109. void (*alloc_req_hdlr)(void *hdlr_data, void *msg, size_t size);
  110. int (*alloc_resp_hdlr)(void *hdlr_data, void *msg, size_t size, void *resp_buf);
  111. void (*relinquish_hdlr)(void *hdlr_data, void *msg, size_t size);
  112. void (*relinquish_memparcel_hdl)(void *hdlr_data, u32 obj_id,
  113. gh_memparcel_handle_t memparcel_hdl);
  114. };
  115. struct mem_buf_msgq_hdlr_info {
  116. const struct mem_buf_msgq_ops *msgq_ops;
  117. void *hdlr_data;
  118. };
  119. static inline u32 get_alloc_req_nr_acl_entries(struct mem_buf_alloc_req *req)
  120. {
  121. return req->acl_desc.n_acl_entries;
  122. }
  123. static inline struct gh_acl_desc *get_alloc_req_gh_acl_desc(struct mem_buf_alloc_req *req)
  124. {
  125. return &req->acl_desc;
  126. }
  127. static inline enum mem_buf_mem_type get_alloc_req_src_mem_type(struct mem_buf_alloc_req *req)
  128. {
  129. return req->src_mem_type;
  130. }
  131. static inline u64 get_alloc_req_size(struct mem_buf_alloc_req *req)
  132. {
  133. return req->size;
  134. }
  135. static inline u64 get_alloc_req_xfer_type(struct mem_buf_alloc_req *req)
  136. {
  137. return req->trans_type;
  138. }
  139. static inline void *get_alloc_req_arb_payload(struct mem_buf_alloc_req *req)
  140. {
  141. void *buf = req;
  142. size_t nr_acl_entries;
  143. size_t payload_offset;
  144. nr_acl_entries = req->acl_desc.n_acl_entries;
  145. if (nr_acl_entries != 1)
  146. return NULL;
  147. payload_offset = offsetof(struct mem_buf_alloc_req,
  148. acl_desc.acl_entries[nr_acl_entries]);
  149. return buf + payload_offset;
  150. }
  151. static inline u32 get_alloc_req_txn_id(struct mem_buf_alloc_req *req)
  152. {
  153. return req->hdr.txn_id;
  154. }
  155. static inline s32 get_alloc_resp_retval(struct mem_buf_alloc_resp *resp)
  156. {
  157. return resp->ret;
  158. }
  159. static inline u32 get_alloc_resp_hdl(struct mem_buf_alloc_resp *resp)
  160. {
  161. return resp->hdl;
  162. }
  163. static inline u32 get_alloc_resp_obj_id(struct mem_buf_alloc_resp *resp)
  164. {
  165. return resp->obj_id;
  166. }
  167. static inline u32 get_relinquish_req_obj_id(struct mem_buf_alloc_relinquish *relinquish_msg)
  168. {
  169. return relinquish_msg->obj_id;
  170. }
  171. #if IS_ENABLED(CONFIG_QCOM_MEM_BUF_MSGQ)
  172. void *mem_buf_msgq_register(const char *msgq_name, struct mem_buf_msgq_hdlr_info *info);
  173. void mem_buf_msgq_unregister(void *mem_buf_msgq_hdl);
  174. void *mem_buf_init_txn(void *mem_buf_msgq_hdl, void *resp_buf);
  175. int mem_buf_msgq_send(void *mem_buf_msgq_hdl, void *msg);
  176. int mem_buf_txn_wait(void *mem_buf_msgq_hdl, void *mem_buf_txn);
  177. void mem_buf_destroy_txn(void *mem_buf_msgq_hdl, void *mem_buf_txn);
  178. int mem_buf_retrieve_txn_id(void *mem_buf_txn);
  179. /*
  180. * It is the caller's responsibility to free the messages returned by
  181. * any functions invoked to construct them via a call to kfree().
  182. */
  183. void *mem_buf_construct_alloc_req(void *mem_buf_txn, size_t alloc_size,
  184. struct gh_acl_desc *acl_desc,
  185. enum mem_buf_mem_type src_mem_type, void *src_data,
  186. u32 trans_type);
  187. void *mem_buf_construct_alloc_resp(void *req_msg, s32 alloc_ret,
  188. gh_memparcel_handle_t memparcel_hdl,
  189. u32 obj_id);
  190. void *mem_buf_construct_relinquish_msg(void *mem_buf_txn, u32 obj_id,
  191. gh_memparcel_handle_t memparcel_hdl);
  192. void *mem_buf_construct_relinquish_resp(void *_msg);
  193. #else
  194. static inline void *mem_buf_msgq_register(const char *msgq_name,
  195. struct mem_buf_msgq_hdlr_info *info)
  196. {
  197. return ERR_PTR(-EOPNOTSUPP);
  198. }
  199. static inline void mem_buf_msgq_unregister(void *mem_buf_msgq_hdl)
  200. {
  201. }
  202. static inline void *mem_buf_init_txn(void *mem_buf_msgq_hdl, void *resp_buf)
  203. {
  204. return ERR_PTR(-EOPNOTSUPP);
  205. }
  206. static inline int mem_buf_msgq_send(void *mem_buf_msgq_hdl, void *msg)
  207. {
  208. return -EOPNOTSUPP;
  209. }
  210. static inline int mem_buf_txn_wait(void *mem_buf_msgq_hdl, void *mem_buf_txn)
  211. {
  212. return -EOPNOTSUPP;
  213. }
  214. static inline void mem_buf_destroy_txn(void *mem_buf_msgq_hdl, void *mem_buf_txn)
  215. {
  216. }
  217. static inline void *mem_buf_construct_alloc_req(void *mem_buf_txn, size_t alloc_size,
  218. struct gh_acl_desc *acl_desc,
  219. enum mem_buf_mem_type src_mem_type, void *src_data,
  220. u32 trans_type)
  221. {
  222. return ERR_PTR(-ENODEV);
  223. }
  224. static inline void *mem_buf_construct_alloc_resp(void *req_msg, s32 alloc_ret,
  225. gh_memparcel_handle_t memparcel_hdl,
  226. u32 obj_id)
  227. {
  228. return ERR_PTR(-ENODEV);
  229. }
  230. static inline void *mem_buf_construct_relinquish_msg(void *mem_buf_txn, u32 obj_id,
  231. gh_memparcel_handle_t memparcel_hdl)
  232. {
  233. return ERR_PTR(-ENODEV);
  234. }
  235. static inline void *mem_buf_construct_relinquish_resp(void *_msg)
  236. {
  237. return ERR_PTR(-ENODEV);
  238. }
  239. static inline int mem_buf_retrieve_txn_id(void *mem_buf_txn)
  240. {
  241. return -ENODEV;
  242. }
  243. #endif
  244. #endif