123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- /* SPDX-License-Identifier: GPL-2.0-only */
- /*
- * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
- */
- #ifndef MEM_BUF_MSGQ_H
- #define MEM_BUF_MSGQ_H
- #include <linux/mem-buf.h>
- #include <linux/types.h>
- /**
- * enum mem_buf_msg_type: Message types used by the membuf driver for
- * communication.
- * @MEM_BUF_ALLOC_REQ: The message is an allocation request from another VM to
- * the receiving VM
- * @MEM_BUF_ALLOC_RESP: The message is a response from a remote VM to an
- * allocation request issued by the receiving VM
- * @MEM_BUF_ALLOC_RELINQUISH: The message is a notification from another VM
- * that the receiving VM can reclaim the memory.
- * @MEM_BUF_ALLOC_RELINQUISH_RESP: Indicates completion of MEM_BUF_ALLOC_RELINQUISH.
- */
- enum mem_buf_msg_type {
- MEM_BUF_ALLOC_REQ,
- MEM_BUF_ALLOC_RESP,
- MEM_BUF_ALLOC_RELINQUISH,
- MEM_BUF_ALLOC_RELINQUISH_RESP,
- MEM_BUF_ALLOC_REQ_MAX,
- };
- /**
- * struct mem_buf_msg_hdr: The header for all membuf messages
- * @txn_id: The transaction ID for the message. This field is only meaningful
- * for request/response type of messages.
- * @msg_type: The type of message.
- * @msg_size: The size of message.
- */
- struct mem_buf_msg_hdr {
- u32 txn_id;
- u32 msg_type;
- u32 msg_size;
- } __packed;
- /**
- * struct mem_buf_alloc_req: The message format for a memory allocation request
- * to another VM.
- * @hdr: Message header
- * @size: The size of the memory allocation to be performed on the remote VM.
- * @src_mem_type: The type of memory that the remote VM should allocate.
- * @trans_type: One of GH_RM_TRANS_TYPE_DONATE/SHARE/LEND
- * @acl_desc: A GH ACL descriptor that describes the VMIDs that will be
- * accessing the memory, as well as what permissions each VMID will have.
- *
- * NOTE: Certain memory types require additional information for the remote VM
- * to interpret. That information should be concatenated with this structure
- * prior to sending the allocation request to the remote VM. For example,
- * with memory type DMAHEAP, the allocation request message will consist of this
- * structure, as well as the name of the heap that will source the allocation.
- */
- struct mem_buf_alloc_req {
- struct mem_buf_msg_hdr hdr;
- u64 size;
- u32 src_mem_type;
- u32 trans_type;
- struct gh_acl_desc acl_desc;
- } __packed;
- /**
- * struct mem_buf_alloc_resp: The message format for a memory allocation
- * request response.
- * @hdr: Message header
- * @ret: Return code from remote VM
- * @hdl: The memparcel handle associated with the memory allocated to the
- * receiving VM. This field is only meaningful if the allocation on the remote
- * VM was carried out successfully, as denoted by @ret.
- * (i.e. memory donation, sharing, or lending).
- * @obj_id: Unique identifier for the memory object associated with handle.
- */
- struct mem_buf_alloc_resp {
- struct mem_buf_msg_hdr hdr;
- s32 ret;
- u32 hdl;
- u32 obj_id;
- } __packed;
- /**
- * struct mem_buf_alloc_relinquish: The message format for a notification
- * that the current VM has relinquished access to the memory lent to it by
- * another VM.
- * @hdr: Message header
- * @hdl: The memparcel handle associated with the memory.
- * @obj_id: Unique identifier for the memory object associated with handle.
- */
- struct mem_buf_alloc_relinquish {
- struct mem_buf_msg_hdr hdr;
- u32 hdl;
- u32 obj_id;
- } __packed;
- /*
- * mem_buf_msgq_ops: A set of ops that are invoked when a message of particular
- * types are received by a mem-buf message queue.
- *
- * The handlers are responsible for freeing the msg buffer that is passed to
- * them.
- *
- * @alloc_req_hdlr: The handler for messages of type MEM_BUF_ALLOC_REQ.
- * @alloc_resp_hdlr: The handler for messages of type MEM_BUF_ALLOC_RESP.
- * @relinquish_hdlr: The handler for messages of type MEM_BUF_ALLOC_RELINQUISH.
- * @relinquish_memparcel_hdl: Callback for relinquishing a memparcel. This is typically used in
- * case an allocation request times out, and the response arrives late.
- * In this case, the transaction will have been aborted, but the memory
- * still needs to be relinquished.
- */
- struct mem_buf_msgq_ops {
- void (*alloc_req_hdlr)(void *hdlr_data, void *msg, size_t size);
- int (*alloc_resp_hdlr)(void *hdlr_data, void *msg, size_t size, void *resp_buf);
- void (*relinquish_hdlr)(void *hdlr_data, void *msg, size_t size);
- void (*relinquish_memparcel_hdl)(void *hdlr_data, u32 obj_id,
- gh_memparcel_handle_t memparcel_hdl);
- };
- struct mem_buf_msgq_hdlr_info {
- const struct mem_buf_msgq_ops *msgq_ops;
- void *hdlr_data;
- };
- static inline u32 get_alloc_req_nr_acl_entries(struct mem_buf_alloc_req *req)
- {
- return req->acl_desc.n_acl_entries;
- }
- static inline struct gh_acl_desc *get_alloc_req_gh_acl_desc(struct mem_buf_alloc_req *req)
- {
- return &req->acl_desc;
- }
- static inline enum mem_buf_mem_type get_alloc_req_src_mem_type(struct mem_buf_alloc_req *req)
- {
- return req->src_mem_type;
- }
- static inline u64 get_alloc_req_size(struct mem_buf_alloc_req *req)
- {
- return req->size;
- }
- static inline u64 get_alloc_req_xfer_type(struct mem_buf_alloc_req *req)
- {
- return req->trans_type;
- }
- static inline void *get_alloc_req_arb_payload(struct mem_buf_alloc_req *req)
- {
- void *buf = req;
- size_t nr_acl_entries;
- size_t payload_offset;
- nr_acl_entries = req->acl_desc.n_acl_entries;
- if (nr_acl_entries != 1)
- return NULL;
- payload_offset = offsetof(struct mem_buf_alloc_req,
- acl_desc.acl_entries[nr_acl_entries]);
- return buf + payload_offset;
- }
- static inline u32 get_alloc_req_txn_id(struct mem_buf_alloc_req *req)
- {
- return req->hdr.txn_id;
- }
- static inline s32 get_alloc_resp_retval(struct mem_buf_alloc_resp *resp)
- {
- return resp->ret;
- }
- static inline u32 get_alloc_resp_hdl(struct mem_buf_alloc_resp *resp)
- {
- return resp->hdl;
- }
- static inline u32 get_alloc_resp_obj_id(struct mem_buf_alloc_resp *resp)
- {
- return resp->obj_id;
- }
- static inline u32 get_relinquish_req_obj_id(struct mem_buf_alloc_relinquish *relinquish_msg)
- {
- return relinquish_msg->obj_id;
- }
- #if IS_ENABLED(CONFIG_QCOM_MEM_BUF_MSGQ)
- void *mem_buf_msgq_register(const char *msgq_name, struct mem_buf_msgq_hdlr_info *info);
- void mem_buf_msgq_unregister(void *mem_buf_msgq_hdl);
- void *mem_buf_init_txn(void *mem_buf_msgq_hdl, void *resp_buf);
- int mem_buf_msgq_send(void *mem_buf_msgq_hdl, void *msg);
- int mem_buf_txn_wait(void *mem_buf_msgq_hdl, void *mem_buf_txn);
- void mem_buf_destroy_txn(void *mem_buf_msgq_hdl, void *mem_buf_txn);
- int mem_buf_retrieve_txn_id(void *mem_buf_txn);
- /*
- * It is the caller's responsibility to free the messages returned by
- * any functions invoked to construct them via a call to kfree().
- */
- void *mem_buf_construct_alloc_req(void *mem_buf_txn, size_t alloc_size,
- struct gh_acl_desc *acl_desc,
- enum mem_buf_mem_type src_mem_type, void *src_data,
- u32 trans_type);
- void *mem_buf_construct_alloc_resp(void *req_msg, s32 alloc_ret,
- gh_memparcel_handle_t memparcel_hdl,
- u32 obj_id);
- void *mem_buf_construct_relinquish_msg(void *mem_buf_txn, u32 obj_id,
- gh_memparcel_handle_t memparcel_hdl);
- void *mem_buf_construct_relinquish_resp(void *_msg);
- #else
- static inline void *mem_buf_msgq_register(const char *msgq_name,
- struct mem_buf_msgq_hdlr_info *info)
- {
- return ERR_PTR(-EOPNOTSUPP);
- }
- static inline void mem_buf_msgq_unregister(void *mem_buf_msgq_hdl)
- {
- }
- static inline void *mem_buf_init_txn(void *mem_buf_msgq_hdl, void *resp_buf)
- {
- return ERR_PTR(-EOPNOTSUPP);
- }
- static inline int mem_buf_msgq_send(void *mem_buf_msgq_hdl, void *msg)
- {
- return -EOPNOTSUPP;
- }
- static inline int mem_buf_txn_wait(void *mem_buf_msgq_hdl, void *mem_buf_txn)
- {
- return -EOPNOTSUPP;
- }
- static inline void mem_buf_destroy_txn(void *mem_buf_msgq_hdl, void *mem_buf_txn)
- {
- }
- static inline void *mem_buf_construct_alloc_req(void *mem_buf_txn, size_t alloc_size,
- struct gh_acl_desc *acl_desc,
- enum mem_buf_mem_type src_mem_type, void *src_data,
- u32 trans_type)
- {
- return ERR_PTR(-ENODEV);
- }
- static inline void *mem_buf_construct_alloc_resp(void *req_msg, s32 alloc_ret,
- gh_memparcel_handle_t memparcel_hdl,
- u32 obj_id)
- {
- return ERR_PTR(-ENODEV);
- }
- static inline void *mem_buf_construct_relinquish_msg(void *mem_buf_txn, u32 obj_id,
- gh_memparcel_handle_t memparcel_hdl)
- {
- return ERR_PTR(-ENODEV);
- }
- static inline void *mem_buf_construct_relinquish_resp(void *_msg)
- {
- return ERR_PTR(-ENODEV);
- }
- static inline int mem_buf_retrieve_txn_id(void *mem_buf_txn)
- {
- return -ENODEV;
- }
- #endif
- #endif
|