blob: 6ea473b0b12fd287cabc5e1a6dd12a65d47d4e8f [file] [log] [blame]
Brad Bishopbec4ebc2022-08-03 09:55:16 -04001From 18b20dea7cf7e8afc26c5d49d5368d3180bd54d7 Mon Sep 17 00:00:00 2001
2From: Julian Hall <julian.hall@arm.com>
3Date: Wed, 8 Dec 2021 16:05:22 +0000
4Subject: [PATCH] Support FFARPC call requests with no shared buffer
5
6To allow simple clients to make RPC calls for service operations
7that take no request parameters and return no response parameters,
8the ffarpc_call_ep.c has been modified to accept call requests
9when no shared buffer exists, as long as there is no request data.
10
11Signed-off-by: Julian Hall <julian.hall@arm.com>
12Change-Id: I83b1bfb719a005922d6394887492d2d272b74907
13
14Upstream-Status: Pending [Not submitted to upstream yet]
15Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
16
17
18---
19 .../rpc/ffarpc/endpoint/ffarpc_call_ep.c | 52 ++++++++++---------
20 1 file changed, 27 insertions(+), 25 deletions(-)
21
22diff --git a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c b/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
23index 17f957c2..a08a250c 100644
24--- a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
25+++ b/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
26@@ -150,29 +150,43 @@ out:
27 static void handle_service_msg(struct ffa_call_ep *call_ep, uint16_t source_id,
28 const uint32_t *req_args, uint32_t *resp_args)
29 {
30- rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
31+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
32 struct call_req call_req;
33
34 uint32_t ifaceid_opcode = req_args[SP_CALL_ARGS_IFACE_ID_OPCODE];
35 int idx = find_shm(call_ep, source_id);
36
37- if (idx < 0) {
38- EMSG("handle service msg error");
39- goto out;
40- }
41-
42 call_req.caller_id = source_id;
43 call_req.interface_id = FFA_CALL_ARGS_EXTRACT_IFACE(ifaceid_opcode);
44 call_req.opcode = FFA_CALL_ARGS_EXTRACT_OPCODE(ifaceid_opcode);
45 call_req.encoding = req_args[SP_CALL_ARGS_ENCODING];
46
47- call_req.req_buf.data = call_ep->shmem_buf[idx];
48 call_req.req_buf.data_len = req_args[SP_CALL_ARGS_REQ_DATA_LEN];
49- call_req.req_buf.size = call_ep->shmem_buf_size[idx];
50-
51- call_req.resp_buf.data = call_ep->shmem_buf[idx];
52 call_req.resp_buf.data_len = 0;
53- call_req.resp_buf.size = call_ep->shmem_buf_size[idx];
54+
55+ if (idx >= 0 && call_ep->shmem_buf[idx]) {
56+ /* A shared buffer is available for call parameters */
57+ call_req.req_buf.data = call_ep->shmem_buf[idx];
58+ call_req.req_buf.size = call_ep->shmem_buf_size[idx];
59+
60+ call_req.resp_buf.data = call_ep->shmem_buf[idx];
61+ call_req.resp_buf.size = call_ep->shmem_buf_size[idx];
62+ }
63+ else if (call_req.req_buf.data_len == 0) {
64+ /* No shared buffer so only allow calls with no request data */
65+ call_req.req_buf.data = NULL;
66+ call_req.req_buf.size = 0;
67+
68+ call_req.resp_buf.data = NULL;
69+ call_req.resp_buf.size = 0;
70+ }
71+ else {
72+ /*
73+ * Caller has specified non-zero length request data but there is
74+ * no shared buffer to carry the request data.
75+ */
76+ goto out;
77+ }
78
79 rpc_status = rpc_interface_receive(call_ep->iface, &call_req);
80
81@@ -223,7 +237,6 @@ void ffa_call_ep_receive(struct ffa_call_ep *call_ep,
82 {
83 const uint32_t *req_args = req_msg->args;
84 uint32_t *resp_args = resp_msg->args;
85- int idx;
86
87 uint16_t source_id = req_msg->source_id;
88 uint32_t ifaceid_opcode = req_args[SP_CALL_ARGS_IFACE_ID_OPCODE];
89@@ -232,18 +245,7 @@ void ffa_call_ep_receive(struct ffa_call_ep *call_ep,
90 /* It's an RPC layer management request */
91 handle_mgmt_msg(call_ep, source_id, req_args, resp_args);
92 } else {
93- /*
94- * Assume anything else is a service request. Service requests
95- * rely on a buffer being shared from the requesting client.
96- * If it hasn't been set-up, fail the request.
97- */
98- idx = find_shm(call_ep, source_id);
99-
100- if (idx >= 0 && call_ep->shmem_buf[idx]) {
101- handle_service_msg(call_ep, source_id, req_args, resp_args);
102- } else {
103- EMSG("shared buffer not found or NULL");
104- set_mgmt_resp_args(resp_args, ifaceid_opcode, TS_RPC_ERROR_NOT_READY);
105- }
106+ /* Assume anything else is a service request */
107+ handle_service_msg(call_ep, source_id, req_args, resp_args);
108 }
109 }