Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame^] | 1 | From 0f02f04c7f0a7130874dc4bc1a500604d580c4dc Mon Sep 17 00:00:00 2001 |
| 2 | From: Imre Kis <imre.kis@arm.com> |
| 3 | Date: Wed, 20 Jul 2022 15:19:17 +0200 |
| 4 | Subject: [PATCH 22/24] Change MM communicate RPC protocol of call endpoint |
| 5 | |
| 6 | Replace buffer address and size parameter by offset in buffer parameter |
| 7 | and move to 64 bit FF-A direct message call. Deny all 32 bit direct |
| 8 | messages in SMM gateway. |
| 9 | |
| 10 | Signed-off-by: Imre Kis <imre.kis@arm.com> |
| 11 | Change-Id: I7a69b440ff9842960229b2bfdd1b5ae5318d9c26 |
| 12 | |
| 13 | Upstream-Status: Pending [In review] |
| 14 | Signed-off-by: Anton Antonov <Anton.Antonov@arm.com> |
| 15 | |
| 16 | --- |
| 17 | .../common/mm_communicate_call_args.h | 15 ++- |
| 18 | .../endpoint/sp/mm_communicate_call_ep.c | 58 ++++----- |
| 19 | .../endpoint/sp/test/mock_mm_service.cpp | 6 +- |
| 20 | .../endpoint/sp/test/mock_mm_service.h | 4 +- |
| 21 | .../sp/test/test_mm_communicate_call_ep.cpp | 110 +++++++++++------- |
| 22 | .../endpoint/sp/test/test_mock_mm_service.cpp | 4 +- |
| 23 | .../smm-gateway/common/smm_gateway_sp.c | 17 ++- |
| 24 | 7 files changed, 123 insertions(+), 91 deletions(-) |
| 25 | |
| 26 | diff --git a/components/rpc/mm_communicate/common/mm_communicate_call_args.h b/components/rpc/mm_communicate/common/mm_communicate_call_args.h |
| 27 | index 7d7311d..280c04d 100644 |
| 28 | --- a/components/rpc/mm_communicate/common/mm_communicate_call_args.h |
| 29 | +++ b/components/rpc/mm_communicate/common/mm_communicate_call_args.h |
| 30 | @@ -1,6 +1,6 @@ |
| 31 | /* SPDX-License-Identifier: BSD-3-Clause */ |
| 32 | /* |
| 33 | - * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. |
| 34 | + * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved. |
| 35 | */ |
| 36 | |
| 37 | #ifndef MM_COMMUNICATE_CALL_ARGS_H_ |
| 38 | @@ -12,13 +12,12 @@ |
| 39 | */ |
| 40 | |
| 41 | /* SP message arg indexes */ |
| 42 | -#define MM_COMMUNICATE_CALL_ARGS_COMM_BUFFER_ADDRESS 0 |
| 43 | -#define MM_COMMUNICATE_CALL_ARGS_COMM_BUFFER_SIZE 1 |
| 44 | +#define MM_COMMUNICATE_CALL_ARGS_COMM_BUFFER_OFFSET 0 |
| 45 | |
| 46 | -#define MM_COMMUNICATE_CALL_ARGS_RETURN_ID 0 |
| 47 | -#define MM_COMMUNICATE_CALL_ARGS_RETURN_CODE 1 |
| 48 | -#define MM_COMMUNICATE_CALL_ARGS_MBZ0 2 |
| 49 | -#define MM_COMMUNICATE_CALL_ARGS_MBZ1 3 |
| 50 | -#define MM_COMMUNICATE_CALL_ARGS_MBZ2 4 |
| 51 | +#define MM_COMMUNICATE_CALL_ARGS_RETURN_CODE 0 |
| 52 | +#define MM_COMMUNICATE_CALL_ARGS_MBZ0 1 |
| 53 | +#define MM_COMMUNICATE_CALL_ARGS_MBZ1 2 |
| 54 | +#define MM_COMMUNICATE_CALL_ARGS_MBZ2 3 |
| 55 | +#define MM_COMMUNICATE_CALL_ARGS_MBZ3 4 |
| 56 | |
| 57 | #endif /* MM_COMMUNICATE_CALL_ARGS_H_ */ |
| 58 | diff --git a/components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.c b/components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.c |
| 59 | index dc49e64..93aa0f4 100644 |
| 60 | --- a/components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.c |
| 61 | +++ b/components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.c |
| 62 | @@ -35,7 +35,8 @@ bool mm_communicate_call_ep_init(struct mm_communicate_ep *call_ep, uint8_t *com |
| 63 | |
| 64 | static int32_t invoke_mm_service(struct mm_communicate_ep *call_ep, uint16_t source_id, |
| 65 | struct mm_service_interface *iface, |
| 66 | - EFI_MM_COMMUNICATE_HEADER *header) |
| 67 | + EFI_MM_COMMUNICATE_HEADER *header, |
| 68 | + size_t buffer_size) |
| 69 | { |
| 70 | rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL; |
| 71 | struct mm_service_call_req call_req = { 0 }; |
| 72 | @@ -49,11 +50,11 @@ static int32_t invoke_mm_service(struct mm_communicate_ep *call_ep, uint16_t sou |
| 73 | */ |
| 74 | call_req.req_buf.data = header->Data; |
| 75 | call_req.req_buf.data_len = header->MessageLength; |
| 76 | - call_req.req_buf.size = call_ep->comm_buffer_size - EFI_MM_COMMUNICATE_HEADER_SIZE; |
| 77 | + call_req.req_buf.size = buffer_size; |
| 78 | |
| 79 | call_req.resp_buf.data = header->Data; |
| 80 | call_req.resp_buf.data_len = 0; |
| 81 | - call_req.resp_buf.size = call_ep->comm_buffer_size - EFI_MM_COMMUNICATE_HEADER_SIZE; |
| 82 | + call_req.resp_buf.size = buffer_size; |
| 83 | |
| 84 | result = iface->receive(iface, &call_req); |
| 85 | |
| 86 | @@ -63,32 +64,38 @@ static int32_t invoke_mm_service(struct mm_communicate_ep *call_ep, uint16_t sou |
| 87 | } |
| 88 | |
| 89 | static int32_t handle_mm_communicate(struct mm_communicate_ep *call_ep, uint16_t source_id, |
| 90 | - uintptr_t buffer_addr, size_t buffer_size) |
| 91 | + size_t buffer_offset) |
| 92 | { |
| 93 | - uintptr_t buffer_arg = 0; |
| 94 | - size_t request_size = 0; |
| 95 | + size_t header_end_offset = 0; |
| 96 | + size_t request_end_offset = 0; |
| 97 | + size_t buffer_size = 0; |
| 98 | EFI_MM_COMMUNICATE_HEADER *header = NULL; |
| 99 | unsigned int i = 0; |
| 100 | |
| 101 | - /* Validating call args according to ARM MM spec 3.2.4 */ |
| 102 | - if (buffer_addr == 0) |
| 103 | + if (ADD_OVERFLOW(buffer_offset, EFI_MM_COMMUNICATE_HEADER_SIZE, &header_end_offset)) |
| 104 | + return MM_RETURN_CODE_INVALID_PARAMETER; |
| 105 | + |
| 106 | + if (call_ep->comm_buffer_size < header_end_offset) |
| 107 | return MM_RETURN_CODE_INVALID_PARAMETER; |
| 108 | |
| 109 | /* Validating comm buffer contents */ |
| 110 | - header = (EFI_MM_COMMUNICATE_HEADER *)call_ep->comm_buffer; |
| 111 | - if (ADD_OVERFLOW(header->MessageLength, EFI_MM_COMMUNICATE_HEADER_SIZE, &request_size)) |
| 112 | + header = (EFI_MM_COMMUNICATE_HEADER *)(call_ep->comm_buffer + buffer_offset); |
| 113 | + if (ADD_OVERFLOW(header_end_offset, header->MessageLength, &request_end_offset)) |
| 114 | return MM_RETURN_CODE_INVALID_PARAMETER; |
| 115 | |
| 116 | - if (call_ep->comm_buffer_size < request_size) |
| 117 | + if (call_ep->comm_buffer_size < request_end_offset) |
| 118 | return MM_RETURN_CODE_INVALID_PARAMETER; |
| 119 | |
| 120 | + buffer_size = call_ep->comm_buffer_size - header_end_offset; |
| 121 | + |
| 122 | /* Finding iface_id by GUID */ |
| 123 | for (i = 0; i < ARRAY_SIZE(call_ep->service_table); i++) { |
| 124 | const struct mm_service_entry *entry = &call_ep->service_table[i]; |
| 125 | |
| 126 | if (entry->iface != NULL && |
| 127 | memcmp(&header->HeaderGuid, &entry->guid, sizeof(entry->guid)) == 0) |
| 128 | - return invoke_mm_service(call_ep, source_id, entry->iface, header); |
| 129 | + return invoke_mm_service(call_ep, source_id, entry->iface, header, |
| 130 | + buffer_size); |
| 131 | } |
| 132 | |
| 133 | return MM_RETURN_CODE_NOT_SUPPORTED; |
| 134 | @@ -123,19 +130,16 @@ void mm_communicate_call_ep_receive(struct mm_communicate_ep *mm_communicate_cal |
| 135 | const struct ffa_direct_msg *req_msg, |
| 136 | struct ffa_direct_msg *resp_msg) |
| 137 | { |
| 138 | - int32_t return_value = 0; |
| 139 | - uintptr_t buffer_address = 0; |
| 140 | - size_t buffer_size = 0; |
| 141 | - |
| 142 | - buffer_address = req_msg->args.args32[MM_COMMUNICATE_CALL_ARGS_COMM_BUFFER_ADDRESS]; |
| 143 | - buffer_size = req_msg->args.args32[MM_COMMUNICATE_CALL_ARGS_COMM_BUFFER_SIZE]; |
| 144 | - |
| 145 | - return_value = handle_mm_communicate(mm_communicate_call_ep, req_msg->source_id, |
| 146 | - buffer_address, buffer_size); |
| 147 | - |
| 148 | - resp_msg->args.args32[MM_COMMUNICATE_CALL_ARGS_RETURN_ID] = ARM_SVC_ID_SP_EVENT_COMPLETE; |
| 149 | - resp_msg->args.args32[MM_COMMUNICATE_CALL_ARGS_RETURN_CODE] = return_value; |
| 150 | - resp_msg->args.args32[MM_COMMUNICATE_CALL_ARGS_MBZ0] = 0; |
| 151 | - resp_msg->args.args32[MM_COMMUNICATE_CALL_ARGS_MBZ1] = 0; |
| 152 | - resp_msg->args.args32[MM_COMMUNICATE_CALL_ARGS_MBZ2] = 0; |
| 153 | + int32_t return_value = MM_RETURN_CODE_NOT_SUPPORTED; |
| 154 | + size_t buffer_offset = req_msg->args.args64[MM_COMMUNICATE_CALL_ARGS_COMM_BUFFER_OFFSET]; |
| 155 | + |
| 156 | + return_value = handle_mm_communicate(mm_communicate_call_ep, |
| 157 | + req_msg->source_id, |
| 158 | + buffer_offset); |
| 159 | + |
| 160 | + resp_msg->args.args64[MM_COMMUNICATE_CALL_ARGS_RETURN_CODE] = return_value; |
| 161 | + resp_msg->args.args64[MM_COMMUNICATE_CALL_ARGS_MBZ0] = 0; |
| 162 | + resp_msg->args.args64[MM_COMMUNICATE_CALL_ARGS_MBZ1] = 0; |
| 163 | + resp_msg->args.args64[MM_COMMUNICATE_CALL_ARGS_MBZ2] = 0; |
| 164 | + resp_msg->args.args64[MM_COMMUNICATE_CALL_ARGS_MBZ3] = 0; |
| 165 | } |
| 166 | diff --git a/components/rpc/mm_communicate/endpoint/sp/test/mock_mm_service.cpp b/components/rpc/mm_communicate/endpoint/sp/test/mock_mm_service.cpp |
| 167 | index a58c33a..0ae2a80 100644 |
| 168 | --- a/components/rpc/mm_communicate/endpoint/sp/test/mock_mm_service.cpp |
| 169 | +++ b/components/rpc/mm_communicate/endpoint/sp/test/mock_mm_service.cpp |
| 170 | @@ -1,6 +1,6 @@ |
| 171 | // SPDX-License-Identifier: BSD-3-Clause |
| 172 | /* |
| 173 | - * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. |
| 174 | + * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved. |
| 175 | */ |
| 176 | |
| 177 | #include <CppUTestExt/MockSupport.h> |
| 178 | @@ -16,7 +16,7 @@ void mock_mm_service_init(void) |
| 179 | |
| 180 | void expect_mock_mm_service_receive(struct mm_service_interface *iface, |
| 181 | const struct mm_service_call_req *req, |
| 182 | - int32_t result) |
| 183 | + int64_t result) |
| 184 | { |
| 185 | mock().expectOneCall("mm_service_receive").onObject(iface). |
| 186 | withOutputParameterReturning("resp_buf_data_len", &req->resp_buf.data_len, |
| 187 | @@ -31,5 +31,5 @@ int32_t mock_mm_service_receive(struct mm_service_interface *iface, |
| 188 | return mock().actualCall("mm_service_receive").onObject(iface). |
| 189 | withOutputParameter("resp_buf_data_len", &req->resp_buf.data_len). |
| 190 | withParameterOfType("mm_service_call_req", "req", req). |
| 191 | - returnIntValue(); |
| 192 | + returnLongIntValue(); |
| 193 | } |
| 194 | diff --git a/components/rpc/mm_communicate/endpoint/sp/test/mock_mm_service.h b/components/rpc/mm_communicate/endpoint/sp/test/mock_mm_service.h |
| 195 | index 768022d..56c8a26 100644 |
| 196 | --- a/components/rpc/mm_communicate/endpoint/sp/test/mock_mm_service.h |
| 197 | +++ b/components/rpc/mm_communicate/endpoint/sp/test/mock_mm_service.h |
| 198 | @@ -1,6 +1,6 @@ |
| 199 | /* SPDX-License-Identifier: BSD-3-Clause */ |
| 200 | /* |
| 201 | - * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. |
| 202 | + * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved. |
| 203 | */ |
| 204 | |
| 205 | #ifndef MOCK_MM_SERVICE_H_ |
| 206 | @@ -16,7 +16,7 @@ void mock_mm_service_init(void); |
| 207 | |
| 208 | void expect_mock_mm_service_receive(struct mm_service_interface *iface, |
| 209 | const struct mm_service_call_req *req, |
| 210 | - int32_t result); |
| 211 | + int64_t result); |
| 212 | |
| 213 | int32_t mock_mm_service_receive(struct mm_service_interface *iface, |
| 214 | struct mm_service_call_req *req); |
| 215 | diff --git a/components/rpc/mm_communicate/endpoint/sp/test/test_mm_communicate_call_ep.cpp b/components/rpc/mm_communicate/endpoint/sp/test/test_mm_communicate_call_ep.cpp |
| 216 | index 55a61fb..5aaa3a6 100644 |
| 217 | --- a/components/rpc/mm_communicate/endpoint/sp/test/test_mm_communicate_call_ep.cpp |
| 218 | +++ b/components/rpc/mm_communicate/endpoint/sp/test/test_mm_communicate_call_ep.cpp |
| 219 | @@ -1,6 +1,6 @@ |
| 220 | // SPDX-License-Identifier: BSD-3-Clause |
| 221 | /* |
| 222 | - * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. |
| 223 | + * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved. |
| 224 | */ |
| 225 | |
| 226 | #include <CppUTest/TestHarness.h> |
| 227 | @@ -32,14 +32,14 @@ TEST_GROUP(mm_communicate_call_ep) |
| 228 | mock().clear(); |
| 229 | } |
| 230 | |
| 231 | - void check_sp_msg(const struct ffa_direct_msg *msg, uint32_t arg0, |
| 232 | - uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4) |
| 233 | + void check_sp_msg(const struct ffa_direct_msg *msg, uint64_t arg0, |
| 234 | + uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) |
| 235 | { |
| 236 | - UNSIGNED_LONGLONGS_EQUAL(arg0, msg->args[0]); |
| 237 | - UNSIGNED_LONGLONGS_EQUAL(arg1, msg->args[1]); |
| 238 | - UNSIGNED_LONGLONGS_EQUAL(arg2, msg->args[2]); |
| 239 | - UNSIGNED_LONGLONGS_EQUAL(arg3, msg->args[3]); |
| 240 | - UNSIGNED_LONGLONGS_EQUAL(arg4, msg->args[4]); |
| 241 | + UNSIGNED_LONGLONGS_EQUAL(arg0, msg->args.args64[0]); |
| 242 | + UNSIGNED_LONGLONGS_EQUAL(arg1, msg->args.args64[1]); |
| 243 | + UNSIGNED_LONGLONGS_EQUAL(arg2, msg->args.args64[2]); |
| 244 | + UNSIGNED_LONGLONGS_EQUAL(arg3, msg->args.args64[3]); |
| 245 | + UNSIGNED_LONGLONGS_EQUAL(arg4, msg->args.args64[4]); |
| 246 | } |
| 247 | |
| 248 | struct mm_communicate_ep call_ep; |
| 249 | @@ -114,59 +114,54 @@ TEST(mm_communicate_call_ep, attach_do_not_fit) |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | -TEST(mm_communicate_call_ep, mm_communicate_no_buffer_arg) |
| 254 | +TEST(mm_communicate_call_ep, mm_communicate_offset_int_overflow) |
| 255 | { |
| 256 | CHECK_TRUE(mm_communicate_call_ep_init(&call_ep, comm_buffer, sizeof(comm_buffer))); |
| 257 | + req_msg.args.args64[0] = 0xffffffffffffffff; |
| 258 | |
| 259 | mm_communicate_call_ep_receive(&call_ep, &req_msg, &resp_msg); |
| 260 | |
| 261 | - check_sp_msg(&resp_msg, ARM_SVC_ID_SP_EVENT_COMPLETE, MM_RETURN_CODE_INVALID_PARAMETER, |
| 262 | - 0, 0, 0); |
| 263 | + check_sp_msg(&resp_msg, MM_RETURN_CODE_INVALID_PARAMETER, 0, 0, 0, 0); |
| 264 | } |
| 265 | |
| 266 | -TEST(mm_communicate_call_ep, mm_communicate_length_overflow) |
| 267 | +TEST(mm_communicate_call_ep, mm_communicate_offset_overflow) |
| 268 | { |
| 269 | CHECK_TRUE(mm_communicate_call_ep_init(&call_ep, comm_buffer, sizeof(comm_buffer))); |
| 270 | + req_msg.args.args64[0] = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE + 1; |
| 271 | + |
| 272 | + mm_communicate_call_ep_receive(&call_ep, &req_msg, &resp_msg); |
| 273 | |
| 274 | - req_msg.args[0] = (uintptr_t)comm_buffer; |
| 275 | - req_msg.args[1] = sizeof(comm_buffer); |
| 276 | + check_sp_msg(&resp_msg, MM_RETURN_CODE_INVALID_PARAMETER, 0, 0, 0, 0); |
| 277 | +} |
| 278 | |
| 279 | +TEST(mm_communicate_call_ep, mm_communicate_length_overflow) |
| 280 | +{ |
| 281 | + CHECK_TRUE(mm_communicate_call_ep_init(&call_ep, comm_buffer, sizeof(comm_buffer))); |
| 282 | header->MessageLength = UINT64_MAX - EFI_MM_COMMUNICATE_HEADER_SIZE + 1; |
| 283 | |
| 284 | mm_communicate_call_ep_receive(&call_ep, &req_msg, &resp_msg); |
| 285 | |
| 286 | - check_sp_msg(&resp_msg, ARM_SVC_ID_SP_EVENT_COMPLETE, MM_RETURN_CODE_INVALID_PARAMETER, |
| 287 | - 0, 0, 0); |
| 288 | + check_sp_msg(&resp_msg, MM_RETURN_CODE_INVALID_PARAMETER, 0, 0, 0, 0); |
| 289 | } |
| 290 | |
| 291 | TEST(mm_communicate_call_ep, mm_communicate_too_large) |
| 292 | { |
| 293 | CHECK_TRUE(mm_communicate_call_ep_init(&call_ep, comm_buffer, sizeof(comm_buffer))); |
| 294 | - |
| 295 | - req_msg.args[0] = (uintptr_t)comm_buffer; |
| 296 | - req_msg.args[1] = sizeof(comm_buffer); |
| 297 | - |
| 298 | header->MessageLength = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE + 1; |
| 299 | |
| 300 | mm_communicate_call_ep_receive(&call_ep, &req_msg, &resp_msg); |
| 301 | |
| 302 | - check_sp_msg(&resp_msg, ARM_SVC_ID_SP_EVENT_COMPLETE, MM_RETURN_CODE_INVALID_PARAMETER, |
| 303 | - 0, 0, 0); |
| 304 | + check_sp_msg(&resp_msg, MM_RETURN_CODE_INVALID_PARAMETER, 0, 0, 0, 0); |
| 305 | } |
| 306 | |
| 307 | TEST(mm_communicate_call_ep, mm_communicate_no_handler) |
| 308 | { |
| 309 | CHECK_TRUE(mm_communicate_call_ep_init(&call_ep, comm_buffer, sizeof(comm_buffer))); |
| 310 | - |
| 311 | - req_msg.args[0] = (uintptr_t)comm_buffer; |
| 312 | - req_msg.args[1] = sizeof(comm_buffer); |
| 313 | - |
| 314 | header->MessageLength = 0; |
| 315 | |
| 316 | mm_communicate_call_ep_receive(&call_ep, &req_msg, &resp_msg); |
| 317 | |
| 318 | - check_sp_msg(&resp_msg, ARM_SVC_ID_SP_EVENT_COMPLETE, MM_RETURN_CODE_NOT_SUPPORTED, |
| 319 | - 0, 0, 0); |
| 320 | + check_sp_msg(&resp_msg, MM_RETURN_CODE_NOT_SUPPORTED, 0, 0, 0, 0); |
| 321 | } |
| 322 | |
| 323 | TEST(mm_communicate_call_ep, mm_communicate_single_handler_not_matching) |
| 324 | @@ -175,16 +170,11 @@ TEST(mm_communicate_call_ep, mm_communicate_single_handler_not_matching) |
| 325 | |
| 326 | CHECK_TRUE(mm_communicate_call_ep_init(&call_ep, comm_buffer, sizeof(comm_buffer))); |
| 327 | mm_communicate_call_ep_attach_service(&call_ep, &guid0, &iface); |
| 328 | - |
| 329 | - req_msg.args[0] = (uintptr_t)comm_buffer; |
| 330 | - req_msg.args[1] = sizeof(comm_buffer); |
| 331 | - |
| 332 | header->MessageLength = 0; |
| 333 | |
| 334 | mm_communicate_call_ep_receive(&call_ep, &req_msg, &resp_msg); |
| 335 | |
| 336 | - check_sp_msg(&resp_msg, ARM_SVC_ID_SP_EVENT_COMPLETE, MM_RETURN_CODE_NOT_SUPPORTED, |
| 337 | - 0, 0, 0); |
| 338 | + check_sp_msg(&resp_msg, MM_RETURN_CODE_NOT_SUPPORTED, 0, 0, 0, 0); |
| 339 | } |
| 340 | |
| 341 | TEST(mm_communicate_call_ep, mm_communicate_single_handler_matching) |
| 342 | @@ -211,19 +201,55 @@ TEST(mm_communicate_call_ep, mm_communicate_single_handler_matching) |
| 343 | CHECK_TRUE(mm_communicate_call_ep_init(&call_ep, comm_buffer, sizeof(comm_buffer))); |
| 344 | mm_communicate_call_ep_attach_service(&call_ep, &guid0, &iface); |
| 345 | |
| 346 | - req_msg.args[0] = (uintptr_t)comm_buffer; |
| 347 | - req_msg.args[1] = sizeof(comm_buffer); |
| 348 | + memcpy(&header->HeaderGuid, &guid0, sizeof(guid0)); |
| 349 | + header->MessageLength = req_len; |
| 350 | + |
| 351 | + expect_mock_mm_service_receive(&iface, &req, MM_RETURN_CODE_SUCCESS); |
| 352 | + |
| 353 | + mm_communicate_call_ep_receive(&call_ep, &req_msg, &resp_msg); |
| 354 | + |
| 355 | + check_sp_msg(&resp_msg, MM_RETURN_CODE_SUCCESS, 0, 0, 0, 0); |
| 356 | +} |
| 357 | + |
| 358 | +TEST(mm_communicate_call_ep, mm_communicate_single_handler_matching_with_offset) |
| 359 | +{ |
| 360 | + const size_t offset = 0x10; |
| 361 | + EFI_MM_COMMUNICATE_HEADER *header = (EFI_MM_COMMUNICATE_HEADER *)(comm_buffer + offset); |
| 362 | + |
| 363 | + const size_t req_len = 16; |
| 364 | + struct mm_service_interface iface = { |
| 365 | + .context = (void *)0x1234, |
| 366 | + .receive = mock_mm_service_receive |
| 367 | + }; |
| 368 | + struct mm_service_call_req req = { |
| 369 | + .guid = &guid0, |
| 370 | + .req_buf = { |
| 371 | + .size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE - offset, |
| 372 | + .data_len = req_len, |
| 373 | + .data = header->Data |
| 374 | + }, |
| 375 | + .resp_buf = { |
| 376 | + .size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE - offset, |
| 377 | + .data_len = 0, |
| 378 | + .data = header->Data |
| 379 | + }, |
| 380 | + }; |
| 381 | + |
| 382 | + CHECK_TRUE(mm_communicate_call_ep_init(&call_ep, comm_buffer, sizeof(comm_buffer))); |
| 383 | + mm_communicate_call_ep_attach_service(&call_ep, &guid0, &iface); |
| 384 | |
| 385 | memcpy(&header->HeaderGuid, &guid0, sizeof(guid0)); |
| 386 | header->MessageLength = req_len; |
| 387 | + req_msg.args.args64[0] = offset; |
| 388 | |
| 389 | expect_mock_mm_service_receive(&iface, &req, MM_RETURN_CODE_SUCCESS); |
| 390 | |
| 391 | mm_communicate_call_ep_receive(&call_ep, &req_msg, &resp_msg); |
| 392 | |
| 393 | - check_sp_msg(&resp_msg, ARM_SVC_ID_SP_EVENT_COMPLETE, MM_RETURN_CODE_SUCCESS, 0, 0, 0); |
| 394 | + check_sp_msg(&resp_msg, MM_RETURN_CODE_SUCCESS, 0, 0, 0, 0); |
| 395 | } |
| 396 | |
| 397 | + |
| 398 | TEST(mm_communicate_call_ep, mm_communicate_single_handler_matching_error) |
| 399 | { |
| 400 | const size_t req_len = 16; |
| 401 | @@ -248,9 +274,6 @@ TEST(mm_communicate_call_ep, mm_communicate_single_handler_matching_error) |
| 402 | CHECK_TRUE(mm_communicate_call_ep_init(&call_ep, comm_buffer, sizeof(comm_buffer))); |
| 403 | mm_communicate_call_ep_attach_service(&call_ep, &guid0, &iface); |
| 404 | |
| 405 | - req_msg.args[0] = (uintptr_t)comm_buffer; |
| 406 | - req_msg.args[1] = sizeof(comm_buffer); |
| 407 | - |
| 408 | memcpy(&header->HeaderGuid, &guid0, sizeof(guid0)); |
| 409 | header->MessageLength = req_len; |
| 410 | |
| 411 | @@ -258,7 +281,7 @@ TEST(mm_communicate_call_ep, mm_communicate_single_handler_matching_error) |
| 412 | |
| 413 | mm_communicate_call_ep_receive(&call_ep, &req_msg, &resp_msg); |
| 414 | |
| 415 | - check_sp_msg(&resp_msg, ARM_SVC_ID_SP_EVENT_COMPLETE, MM_RETURN_CODE_NO_MEMORY, 0, 0, 0); |
| 416 | + check_sp_msg(&resp_msg, MM_RETURN_CODE_NO_MEMORY, 0, 0, 0, 0); |
| 417 | } |
| 418 | |
| 419 | TEST(mm_communicate_call_ep, mm_communicate_two_handlers) |
| 420 | @@ -290,9 +313,6 @@ TEST(mm_communicate_call_ep, mm_communicate_two_handlers) |
| 421 | mm_communicate_call_ep_attach_service(&call_ep, &guid0, &iface0); |
| 422 | mm_communicate_call_ep_attach_service(&call_ep, &guid1, &iface1); |
| 423 | |
| 424 | - req_msg.args[0] = (uintptr_t)comm_buffer; |
| 425 | - req_msg.args[1] = sizeof(comm_buffer); |
| 426 | - |
| 427 | memcpy(&header->HeaderGuid, &guid1, sizeof(guid0)); |
| 428 | header->MessageLength = req_len; |
| 429 | |
| 430 | @@ -300,5 +320,5 @@ TEST(mm_communicate_call_ep, mm_communicate_two_handlers) |
| 431 | |
| 432 | mm_communicate_call_ep_receive(&call_ep, &req_msg, &resp_msg); |
| 433 | |
| 434 | - check_sp_msg(&resp_msg, ARM_SVC_ID_SP_EVENT_COMPLETE, MM_RETURN_CODE_SUCCESS, 0, 0, 0); |
| 435 | + check_sp_msg(&resp_msg, MM_RETURN_CODE_SUCCESS, 0, 0, 0, 0); |
| 436 | } |
| 437 | diff --git a/components/rpc/mm_communicate/endpoint/sp/test/test_mock_mm_service.cpp b/components/rpc/mm_communicate/endpoint/sp/test/test_mock_mm_service.cpp |
| 438 | index 360a8fa..600386e 100644 |
| 439 | --- a/components/rpc/mm_communicate/endpoint/sp/test/test_mock_mm_service.cpp |
| 440 | +++ b/components/rpc/mm_communicate/endpoint/sp/test/test_mock_mm_service.cpp |
| 441 | @@ -1,6 +1,6 @@ |
| 442 | // SPDX-License-Identifier: BSD-3-Clause |
| 443 | /* |
| 444 | - * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. |
| 445 | + * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved. |
| 446 | */ |
| 447 | |
| 448 | #include <CppUTest/TestHarness.h> |
| 449 | @@ -44,7 +44,7 @@ TEST(mock_mm_service, receive) |
| 450 | .data = (void *)0x2345 |
| 451 | } |
| 452 | }; |
| 453 | - int32_t result = -123456; |
| 454 | + int64_t result = -123456; |
| 455 | |
| 456 | expect_mock_mm_service_receive(&iface, &req, result); |
| 457 | LONGS_EQUAL(result, mock_mm_service_receive(&iface, &req)); |
| 458 | diff --git a/deployments/smm-gateway/common/smm_gateway_sp.c b/deployments/smm-gateway/common/smm_gateway_sp.c |
| 459 | index 3697b7f..3062877 100644 |
| 460 | --- a/deployments/smm-gateway/common/smm_gateway_sp.c |
| 461 | +++ b/deployments/smm-gateway/common/smm_gateway_sp.c |
| 462 | @@ -11,6 +11,7 @@ |
| 463 | #include "components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.h" |
| 464 | #include "components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.h" |
| 465 | #include "platform/interface/memory_region.h" |
| 466 | +#include "protocols/common/mm/mm_smc.h" |
| 467 | #include <ffa_api.h> |
| 468 | #include <sp_api.h> |
| 469 | #include <sp_messaging.h> |
| 470 | @@ -68,12 +69,20 @@ void __noreturn sp_main(struct ffa_init_info *init_info) |
| 471 | ffa_msg_wait(&req_msg); |
| 472 | |
| 473 | while (1) { |
| 474 | + if (FFA_IS_32_BIT_FUNC(req_msg.function_id)) { |
| 475 | + EMSG("MM communicate over 32 bit FF-A messages is not supported"); |
| 476 | + ffa_msg_send_direct_resp_32(req_msg.destination_id, req_msg.source_id, |
| 477 | + MM_RETURN_CODE_NOT_SUPPORTED, 0, 0, 0, 0, |
| 478 | + &req_msg); |
| 479 | + continue; |
| 480 | + } |
| 481 | + |
| 482 | mm_communicate_call_ep_receive(&mm_communicate_call_ep, &req_msg, &resp_msg); |
| 483 | |
| 484 | - ffa_msg_send_direct_resp_32(req_msg.destination_id, |
| 485 | - req_msg.source_id, resp_msg.args.args32[0], |
| 486 | - resp_msg.args.args32[1], resp_msg.args.args32[2], |
| 487 | - resp_msg.args.args32[3], resp_msg.args.args32[4], |
| 488 | + ffa_msg_send_direct_resp_64(req_msg.destination_id, |
| 489 | + req_msg.source_id, resp_msg.args.args64[0], |
| 490 | + resp_msg.args.args64[1], resp_msg.args.args64[2], |
| 491 | + resp_msg.args.args64[3], resp_msg.args.args64[4], |
| 492 | &req_msg); |
| 493 | } |
| 494 | |
| 495 | -- |
| 496 | 2.17.1 |
| 497 | |