blob: 6ea473b0b12fd287cabc5e1a6dd12a65d47d4e8f [file] [log] [blame]
From 18b20dea7cf7e8afc26c5d49d5368d3180bd54d7 Mon Sep 17 00:00:00 2001
From: Julian Hall <julian.hall@arm.com>
Date: Wed, 8 Dec 2021 16:05:22 +0000
Subject: [PATCH] Support FFARPC call requests with no shared buffer
To allow simple clients to make RPC calls for service operations
that take no request parameters and return no response parameters,
the ffarpc_call_ep.c has been modified to accept call requests
when no shared buffer exists, as long as there is no request data.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I83b1bfb719a005922d6394887492d2d272b74907
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
---
.../rpc/ffarpc/endpoint/ffarpc_call_ep.c | 52 ++++++++++---------
1 file changed, 27 insertions(+), 25 deletions(-)
diff --git a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c b/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
index 17f957c2..a08a250c 100644
--- a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
+++ b/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
@@ -150,29 +150,43 @@ out:
static void handle_service_msg(struct ffa_call_ep *call_ep, uint16_t source_id,
const uint32_t *req_args, uint32_t *resp_args)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
struct call_req call_req;
uint32_t ifaceid_opcode = req_args[SP_CALL_ARGS_IFACE_ID_OPCODE];
int idx = find_shm(call_ep, source_id);
- if (idx < 0) {
- EMSG("handle service msg error");
- goto out;
- }
-
call_req.caller_id = source_id;
call_req.interface_id = FFA_CALL_ARGS_EXTRACT_IFACE(ifaceid_opcode);
call_req.opcode = FFA_CALL_ARGS_EXTRACT_OPCODE(ifaceid_opcode);
call_req.encoding = req_args[SP_CALL_ARGS_ENCODING];
- call_req.req_buf.data = call_ep->shmem_buf[idx];
call_req.req_buf.data_len = req_args[SP_CALL_ARGS_REQ_DATA_LEN];
- call_req.req_buf.size = call_ep->shmem_buf_size[idx];
-
- call_req.resp_buf.data = call_ep->shmem_buf[idx];
call_req.resp_buf.data_len = 0;
- call_req.resp_buf.size = call_ep->shmem_buf_size[idx];
+
+ if (idx >= 0 && call_ep->shmem_buf[idx]) {
+ /* A shared buffer is available for call parameters */
+ call_req.req_buf.data = call_ep->shmem_buf[idx];
+ call_req.req_buf.size = call_ep->shmem_buf_size[idx];
+
+ call_req.resp_buf.data = call_ep->shmem_buf[idx];
+ call_req.resp_buf.size = call_ep->shmem_buf_size[idx];
+ }
+ else if (call_req.req_buf.data_len == 0) {
+ /* No shared buffer so only allow calls with no request data */
+ call_req.req_buf.data = NULL;
+ call_req.req_buf.size = 0;
+
+ call_req.resp_buf.data = NULL;
+ call_req.resp_buf.size = 0;
+ }
+ else {
+ /*
+ * Caller has specified non-zero length request data but there is
+ * no shared buffer to carry the request data.
+ */
+ goto out;
+ }
rpc_status = rpc_interface_receive(call_ep->iface, &call_req);
@@ -223,7 +237,6 @@ void ffa_call_ep_receive(struct ffa_call_ep *call_ep,
{
const uint32_t *req_args = req_msg->args;
uint32_t *resp_args = resp_msg->args;
- int idx;
uint16_t source_id = req_msg->source_id;
uint32_t ifaceid_opcode = req_args[SP_CALL_ARGS_IFACE_ID_OPCODE];
@@ -232,18 +245,7 @@ void ffa_call_ep_receive(struct ffa_call_ep *call_ep,
/* It's an RPC layer management request */
handle_mgmt_msg(call_ep, source_id, req_args, resp_args);
} else {
- /*
- * Assume anything else is a service request. Service requests
- * rely on a buffer being shared from the requesting client.
- * If it hasn't been set-up, fail the request.
- */
- idx = find_shm(call_ep, source_id);
-
- if (idx >= 0 && call_ep->shmem_buf[idx]) {
- handle_service_msg(call_ep, source_id, req_args, resp_args);
- } else {
- EMSG("shared buffer not found or NULL");
- set_mgmt_resp_args(resp_args, ifaceid_opcode, TS_RPC_ERROR_NOT_READY);
- }
+ /* Assume anything else is a service request */
+ handle_service_msg(call_ep, source_id, req_args, resp_args);
}
}