1 /* 2 * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 #include <errno.h> 7 8 #include <common/debug.h> 9 #include <common/runtime_svc.h> 10 #include <lib/object_pool.h> 11 #include <lib/spinlock.h> 12 #include <lib/xlat_tables/xlat_tables_v2.h> 13 #include <services/ffa_svc.h> 14 #include "spmc.h" 15 #include "spmc_shared_mem.h" 16 17 #include <platform_def.h> 18 19 /** 20 * struct spmc_shmem_obj - Shared memory object. 21 * @desc_size: Size of @desc. 22 * @desc_filled: Size of @desc already received. 23 * @in_use: Number of clients that have called ffa_mem_retrieve_req 24 * without a matching ffa_mem_relinquish call. 25 * @desc: FF-A memory region descriptor passed in ffa_mem_share. 26 */ 27 struct spmc_shmem_obj { 28 size_t desc_size; 29 size_t desc_filled; 30 size_t in_use; 31 struct ffa_mtd_v1_0 desc; 32 }; 33 34 /* 35 * Declare our data structure to store the metadata of memory share requests. 36 * The main datastore is allocated on a per platform basis to ensure enough 37 * storage can be made available. 38 * The address of the data store will be populated by the SPMC during its 39 * initialization. 40 */ 41 42 struct spmc_shmem_obj_state spmc_shmem_obj_state = { 43 /* Set start value for handle so top 32 bits are needed quickly. */ 44 .next_handle = 0xffffffc0U, 45 }; 46 47 /** 48 * spmc_shmem_obj_size - Convert from descriptor size to object size. 49 * @desc_size: Size of struct ffa_memory_region_descriptor object. 50 * 51 * Return: Size of struct spmc_shmem_obj object. 52 */ 53 static size_t spmc_shmem_obj_size(size_t desc_size) 54 { 55 return desc_size + offsetof(struct spmc_shmem_obj, desc); 56 } 57 58 /** 59 * spmc_shmem_obj_alloc - Allocate struct spmc_shmem_obj. 60 * @state: Global state. 61 * @desc_size: Size of struct ffa_memory_region_descriptor object that 62 * allocated object will hold. 63 * 64 * Return: Pointer to newly allocated object, or %NULL if there not enough space 65 * left. The returned pointer is only valid while @state is locked, to 66 * used it again after unlocking @state, spmc_shmem_obj_lookup must be 67 * called. 68 */ 69 static struct spmc_shmem_obj * 70 spmc_shmem_obj_alloc(struct spmc_shmem_obj_state *state, size_t desc_size) 71 { 72 struct spmc_shmem_obj *obj; 73 size_t free = state->data_size - state->allocated; 74 75 if (state->data == NULL) { 76 ERROR("Missing shmem datastore!\n"); 77 return NULL; 78 } 79 80 if (spmc_shmem_obj_size(desc_size) > free) { 81 WARN("%s(0x%zx) failed, free 0x%zx\n", 82 __func__, desc_size, free); 83 return NULL; 84 } 85 obj = (struct spmc_shmem_obj *)(state->data + state->allocated); 86 obj->desc = (struct ffa_mtd_v1_0) {0}; 87 obj->desc_size = desc_size; 88 obj->desc_filled = 0; 89 obj->in_use = 0; 90 state->allocated += spmc_shmem_obj_size(desc_size); 91 return obj; 92 } 93 94 /** 95 * spmc_shmem_obj_free - Free struct spmc_shmem_obj. 96 * @state: Global state. 97 * @obj: Object to free. 98 * 99 * Release memory used by @obj. Other objects may move, so on return all 100 * pointers to struct spmc_shmem_obj object should be considered invalid, not 101 * just @obj. 102 * 103 * The current implementation always compacts the remaining objects to simplify 104 * the allocator and to avoid fragmentation. 105 */ 106 107 static void spmc_shmem_obj_free(struct spmc_shmem_obj_state *state, 108 struct spmc_shmem_obj *obj) 109 { 110 size_t free_size = spmc_shmem_obj_size(obj->desc_size); 111 uint8_t *shift_dest = (uint8_t *)obj; 112 uint8_t *shift_src = shift_dest + free_size; 113 size_t shift_size = state->allocated - (shift_src - state->data); 114 115 if (shift_size != 0U) { 116 memmove(shift_dest, shift_src, shift_size); 117 } 118 state->allocated -= free_size; 119 } 120 121 /** 122 * spmc_shmem_obj_lookup - Lookup struct spmc_shmem_obj by handle. 123 * @state: Global state. 124 * @handle: Unique handle of object to return. 125 * 126 * Return: struct spmc_shmem_obj_state object with handle matching @handle. 127 * %NULL, if not object in @state->data has a matching handle. 128 */ 129 static struct spmc_shmem_obj * 130 spmc_shmem_obj_lookup(struct spmc_shmem_obj_state *state, uint64_t handle) 131 { 132 uint8_t *curr = state->data; 133 134 while (curr - state->data < state->allocated) { 135 struct spmc_shmem_obj *obj = (struct spmc_shmem_obj *)curr; 136 137 if (obj->desc.handle == handle) { 138 return obj; 139 } 140 curr += spmc_shmem_obj_size(obj->desc_size); 141 } 142 return NULL; 143 } 144 145 static struct ffa_comp_mrd * 146 spmc_shmem_obj_get_comp_mrd(struct spmc_shmem_obj *obj) 147 { 148 return (struct ffa_comp_mrd *) 149 ((uint8_t *)(&obj->desc) + obj->desc.emad[0].comp_mrd_offset); 150 } 151 152 /** 153 * spmc_shmem_obj_ffa_constituent_size - Calculate variable size part of obj. 154 * @obj: Object containing ffa_memory_region_descriptor. 155 * 156 * Return: Size of ffa_constituent_memory_region_descriptors in @obj. 157 */ 158 static size_t 159 spmc_shmem_obj_ffa_constituent_size(struct spmc_shmem_obj *obj) 160 { 161 return spmc_shmem_obj_get_comp_mrd(obj)->address_range_count * 162 sizeof(struct ffa_cons_mrd); 163 } 164 165 /** 166 * spmc_shmem_check_obj - Check that counts in descriptor match overall size. 167 * @obj: Object containing ffa_memory_region_descriptor. 168 * 169 * Return: 0 if object is valid, -EINVAL if constituent_memory_region_descriptor 170 * offset or count is invalid. 171 */ 172 static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj) 173 { 174 if (obj->desc.emad_count == 0U) { 175 WARN("%s: unsupported attribute desc count %u.\n", 176 __func__, obj->desc.emad_count); 177 return -EINVAL; 178 } 179 180 /* 181 * Ensure the emad array lies within the bounds of the descriptor by 182 * checking the address of the element past the end of the array. 183 */ 184 if ((uintptr_t) &obj->desc.emad[obj->desc.emad_count] > 185 (uintptr_t)((uint8_t *) &obj->desc + obj->desc_size)) { 186 WARN("Invalid emad access.\n"); 187 return -EINVAL; 188 } 189 190 for (size_t emad_num = 0; emad_num < obj->desc.emad_count; emad_num++) { 191 size_t size; 192 size_t count; 193 size_t expected_size; 194 size_t total_page_count; 195 struct ffa_comp_mrd *comp; 196 197 uint32_t offset = obj->desc.emad[emad_num].comp_mrd_offset; 198 size_t header_emad_size = sizeof(obj->desc) + 199 obj->desc.emad_count * sizeof(obj->desc.emad[emad_num]); 200 201 if (offset < header_emad_size) { 202 WARN("%s: invalid object, offset %u < header + emad %zu\n", 203 __func__, offset, header_emad_size); 204 return -EINVAL; 205 } 206 207 size = obj->desc_size; 208 209 if (offset > size) { 210 WARN("%s: invalid object, offset %u > total size %zu\n", 211 __func__, offset, obj->desc_size); 212 return -EINVAL; 213 } 214 size -= offset; 215 216 if (size < sizeof(struct ffa_comp_mrd)) { 217 WARN("%s: invalid object, offset %u, total size %zu, no header space.\n", 218 __func__, offset, obj->desc_size); 219 return -EINVAL; 220 } 221 size -= sizeof(struct ffa_comp_mrd); 222 223 count = size / sizeof(struct ffa_cons_mrd); 224 225 comp = spmc_shmem_obj_get_comp_mrd(obj); 226 227 if (comp->address_range_count != count) { 228 WARN("%s: invalid object, desc count %u != %zu\n", 229 __func__, comp->address_range_count, count); 230 return -EINVAL; 231 } 232 233 expected_size = offset + sizeof(*comp) + 234 spmc_shmem_obj_ffa_constituent_size(obj); 235 if (expected_size != obj->desc_size) { 236 WARN("%s: invalid object, computed size %zu != size %zu\n", 237 __func__, expected_size, obj->desc_size); 238 return -EINVAL; 239 } 240 241 if (obj->desc_filled < obj->desc_size) { 242 /* 243 * The whole descriptor has not yet been received. 244 * Skip final checks. 245 */ 246 return 0; 247 } 248 249 total_page_count = 0; 250 251 for (size_t i = 0; i < count; i++) { 252 total_page_count += 253 comp->address_range_array[i].page_count; 254 } 255 if (comp->total_page_count != total_page_count) { 256 WARN("%s: invalid object, desc total_page_count %u != %zu\n", 257 __func__, comp->total_page_count, 258 total_page_count); 259 return -EINVAL; 260 } 261 } 262 263 return 0; 264 } 265 266 static long spmc_ffa_fill_desc(struct mailbox *mbox, 267 struct spmc_shmem_obj *obj, 268 uint32_t fragment_length, 269 ffa_mtd_flag32_t mtd_flag, 270 void *smc_handle) 271 { 272 int ret; 273 uint32_t handle_low; 274 uint32_t handle_high; 275 276 if (mbox->rxtx_page_count == 0U) { 277 WARN("%s: buffer pair not registered.\n", __func__); 278 ret = -EINVAL; 279 goto err_arg; 280 } 281 282 if (fragment_length > mbox->rxtx_page_count * PAGE_SIZE_4KB) { 283 WARN("%s: bad fragment size %u > %u buffer size\n", __func__, 284 fragment_length, mbox->rxtx_page_count * PAGE_SIZE_4KB); 285 ret = -EINVAL; 286 goto err_arg; 287 } 288 289 memcpy((uint8_t *)&obj->desc + obj->desc_filled, 290 (uint8_t *) mbox->tx_buffer, 291 fragment_length); 292 293 if (fragment_length > obj->desc_size - obj->desc_filled) { 294 WARN("%s: bad fragment size %u > %zu remaining\n", __func__, 295 fragment_length, obj->desc_size - obj->desc_filled); 296 ret = -EINVAL; 297 goto err_arg; 298 } 299 300 /* Ensure that the sender ID resides in the normal world. */ 301 if (ffa_is_secure_world_id(obj->desc.sender_id)) { 302 WARN("%s: Invalid sender ID 0x%x.\n", 303 __func__, obj->desc.sender_id); 304 ret = FFA_ERROR_DENIED; 305 goto err_arg; 306 } 307 308 /* 309 * We don't currently support any optional flags so ensure none are 310 * requested. 311 */ 312 if (obj->desc.flags != 0U && mtd_flag != 0U && 313 (obj->desc.flags != mtd_flag)) { 314 WARN("%s: invalid memory transaction flags %u != %u\n", 315 __func__, obj->desc.flags, mtd_flag); 316 ret = -EINVAL; 317 goto err_arg; 318 } 319 320 if (obj->desc_filled == 0U) { 321 /* First fragment, descriptor header has been copied */ 322 obj->desc.handle = spmc_shmem_obj_state.next_handle++; 323 obj->desc.flags |= mtd_flag; 324 } 325 326 obj->desc_filled += fragment_length; 327 328 ret = spmc_shmem_check_obj(obj); 329 if (ret != 0) { 330 goto err_bad_desc; 331 } 332 333 handle_low = (uint32_t)obj->desc.handle; 334 handle_high = obj->desc.handle >> 32; 335 336 if (obj->desc_filled != obj->desc_size) { 337 SMC_RET8(smc_handle, FFA_MEM_FRAG_RX, handle_low, 338 handle_high, obj->desc_filled, 339 (uint32_t)obj->desc.sender_id << 16, 0, 0, 0); 340 } 341 342 /* The full descriptor has been received, perform any final checks. */ 343 344 /* 345 * If a partition ID resides in the secure world validate that the 346 * partition ID is for a known partition. Ignore any partition ID 347 * belonging to the normal world as it is assumed the Hypervisor will 348 * have validated these. 349 */ 350 for (size_t i = 0; i < obj->desc.emad_count; i++) { 351 ffa_endpoint_id16_t ep_id = obj->desc.emad[i].mapd.endpoint_id; 352 353 if (ffa_is_secure_world_id(ep_id)) { 354 if (spmc_get_sp_ctx(ep_id) == NULL) { 355 WARN("%s: Invalid receiver id 0x%x\n", 356 __func__, ep_id); 357 ret = FFA_ERROR_INVALID_PARAMETER; 358 goto err_bad_desc; 359 } 360 } 361 } 362 363 /* Ensure partition IDs are not duplicated. */ 364 for (size_t i = 0; i < obj->desc.emad_count; i++) { 365 for (size_t j = i + 1; j < obj->desc.emad_count; j++) { 366 if (obj->desc.emad[i].mapd.endpoint_id == 367 obj->desc.emad[j].mapd.endpoint_id) { 368 ret = FFA_ERROR_INVALID_PARAMETER; 369 goto err_bad_desc; 370 } 371 } 372 } 373 374 SMC_RET8(smc_handle, FFA_SUCCESS_SMC32, 0, handle_low, handle_high, 0, 375 0, 0, 0); 376 377 err_bad_desc: 378 err_arg: 379 spmc_shmem_obj_free(&spmc_shmem_obj_state, obj); 380 return spmc_ffa_error_return(smc_handle, FFA_ERROR_INVALID_PARAMETER); 381 } 382 383 /** 384 * spmc_ffa_mem_send - FFA_MEM_SHARE/LEND implementation. 385 * @client: Client state. 386 * @total_length: Total length of shared memory descriptor. 387 * @fragment_length: Length of fragment of shared memory descriptor passed in 388 * this call. 389 * @address: Not supported, must be 0. 390 * @page_count: Not supported, must be 0. 391 * @smc_handle: Handle passed to smc call. Used to return 392 * FFA_MEM_FRAG_RX or SMC_FC_FFA_SUCCESS. 393 * 394 * Implements a subset of the FF-A FFA_MEM_SHARE and FFA_MEM_LEND calls needed 395 * to share or lend memory from non-secure os to secure os (with no stream 396 * endpoints). 397 * 398 * Return: 0 on success, error code on failure. 399 */ 400 long spmc_ffa_mem_send(uint32_t smc_fid, 401 bool secure_origin, 402 uint64_t total_length, 403 uint32_t fragment_length, 404 uint64_t address, 405 uint32_t page_count, 406 void *cookie, 407 void *handle, 408 uint64_t flags) 409 410 { 411 long ret; 412 struct spmc_shmem_obj *obj; 413 struct mailbox *mbox = spmc_get_mbox_desc(secure_origin); 414 ffa_mtd_flag32_t mtd_flag; 415 416 if (address != 0U || page_count != 0U) { 417 WARN("%s: custom memory region for message not supported.\n", 418 __func__); 419 return spmc_ffa_error_return(handle, 420 FFA_ERROR_INVALID_PARAMETER); 421 } 422 423 if (secure_origin) { 424 WARN("%s: unsupported share direction.\n", __func__); 425 return spmc_ffa_error_return(handle, 426 FFA_ERROR_INVALID_PARAMETER); 427 } 428 429 if (fragment_length < sizeof(obj->desc)) { 430 WARN("%s: bad first fragment size %u < %zu\n", 431 __func__, fragment_length, sizeof(obj->desc)); 432 return spmc_ffa_error_return(handle, 433 FFA_ERROR_INVALID_PARAMETER); 434 } 435 436 if ((smc_fid & FUNCID_NUM_MASK) == FFA_FNUM_MEM_SHARE) { 437 mtd_flag = FFA_MTD_FLAG_TYPE_SHARE_MEMORY; 438 } else if ((smc_fid & FUNCID_NUM_MASK) == FFA_FNUM_MEM_LEND) { 439 mtd_flag = FFA_MTD_FLAG_TYPE_LEND_MEMORY; 440 } else { 441 WARN("%s: invalid memory management operation.\n", __func__); 442 return spmc_ffa_error_return(handle, 443 FFA_ERROR_INVALID_PARAMETER); 444 } 445 446 spin_lock(&spmc_shmem_obj_state.lock); 447 448 obj = spmc_shmem_obj_alloc(&spmc_shmem_obj_state, total_length); 449 if (obj == NULL) { 450 ret = FFA_ERROR_NO_MEMORY; 451 goto err_unlock; 452 } 453 454 spin_lock(&mbox->lock); 455 ret = spmc_ffa_fill_desc(mbox, obj, fragment_length, mtd_flag, handle); 456 spin_unlock(&mbox->lock); 457 458 spin_unlock(&spmc_shmem_obj_state.lock); 459 return ret; 460 461 err_unlock: 462 spin_unlock(&spmc_shmem_obj_state.lock); 463 return spmc_ffa_error_return(handle, ret); 464 } 465 466 /** 467 * spmc_ffa_mem_frag_tx - FFA_MEM_FRAG_TX implementation. 468 * @client: Client state. 469 * @handle_low: Handle_low value returned from FFA_MEM_FRAG_RX. 470 * @handle_high: Handle_high value returned from FFA_MEM_FRAG_RX. 471 * @fragment_length: Length of fragments transmitted. 472 * @sender_id: Vmid of sender in bits [31:16] 473 * @smc_handle: Handle passed to smc call. Used to return 474 * FFA_MEM_FRAG_RX or SMC_FC_FFA_SUCCESS. 475 * 476 * Return: @smc_handle on success, error code on failure. 477 */ 478 long spmc_ffa_mem_frag_tx(uint32_t smc_fid, 479 bool secure_origin, 480 uint64_t handle_low, 481 uint64_t handle_high, 482 uint32_t fragment_length, 483 uint32_t sender_id, 484 void *cookie, 485 void *handle, 486 uint64_t flags) 487 { 488 long ret; 489 uint32_t desc_sender_id; 490 struct mailbox *mbox = spmc_get_mbox_desc(secure_origin); 491 492 struct spmc_shmem_obj *obj; 493 uint64_t mem_handle = handle_low | (((uint64_t)handle_high) << 32); 494 495 spin_lock(&spmc_shmem_obj_state.lock); 496 497 obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, mem_handle); 498 if (obj == NULL) { 499 WARN("%s: invalid handle, 0x%lx, not a valid handle.\n", 500 __func__, mem_handle); 501 ret = FFA_ERROR_INVALID_PARAMETER; 502 goto err_unlock; 503 } 504 505 desc_sender_id = (uint32_t)obj->desc.sender_id << 16; 506 if (sender_id != desc_sender_id) { 507 WARN("%s: invalid sender_id 0x%x != 0x%x\n", __func__, 508 sender_id, desc_sender_id); 509 ret = FFA_ERROR_INVALID_PARAMETER; 510 goto err_unlock; 511 } 512 513 if (obj->desc_filled == obj->desc_size) { 514 WARN("%s: object desc already filled, %zu\n", __func__, 515 obj->desc_filled); 516 ret = FFA_ERROR_INVALID_PARAMETER; 517 goto err_unlock; 518 } 519 520 spin_lock(&mbox->lock); 521 ret = spmc_ffa_fill_desc(mbox, obj, fragment_length, 0, handle); 522 spin_unlock(&mbox->lock); 523 524 spin_unlock(&spmc_shmem_obj_state.lock); 525 return ret; 526 527 err_unlock: 528 spin_unlock(&spmc_shmem_obj_state.lock); 529 return spmc_ffa_error_return(handle, ret); 530 } 531 532 /** 533 * spmc_ffa_mem_retrieve_req - FFA_MEM_RETRIEVE_REQ implementation. 534 * @smc_fid: FID of SMC 535 * @total_length: Total length of retrieve request descriptor if this is 536 * the first call. Otherwise (unsupported) must be 0. 537 * @fragment_length: Length of fragment of retrieve request descriptor passed 538 * in this call. Only @fragment_length == @length is 539 * supported by this implementation. 540 * @address: Not supported, must be 0. 541 * @page_count: Not supported, must be 0. 542 * @smc_handle: Handle passed to smc call. Used to return 543 * FFA_MEM_RETRIEVE_RESP. 544 * 545 * Implements a subset of the FF-A FFA_MEM_RETRIEVE_REQ call. 546 * Used by secure os to retrieve memory already shared by non-secure os. 547 * If the data does not fit in a single FFA_MEM_RETRIEVE_RESP message, 548 * the client must call FFA_MEM_FRAG_RX until the full response has been 549 * received. 550 * 551 * Return: @handle on success, error code on failure. 552 */ 553 long 554 spmc_ffa_mem_retrieve_req(uint32_t smc_fid, 555 bool secure_origin, 556 uint32_t total_length, 557 uint32_t fragment_length, 558 uint64_t address, 559 uint32_t page_count, 560 void *cookie, 561 void *handle, 562 uint64_t flags) 563 { 564 int ret; 565 size_t buf_size; 566 size_t copy_size; 567 struct ffa_mtd_v1_0 *resp; 568 const struct ffa_mtd_v1_0 *req; 569 struct spmc_shmem_obj *obj = NULL; 570 struct mailbox *mbox = spmc_get_mbox_desc(secure_origin); 571 572 if (!secure_origin) { 573 WARN("%s: unsupported retrieve req direction.\n", __func__); 574 return spmc_ffa_error_return(handle, 575 FFA_ERROR_INVALID_PARAMETER); 576 } 577 578 if (address != 0U || page_count != 0U) { 579 WARN("%s: custom memory region not supported.\n", __func__); 580 return spmc_ffa_error_return(handle, 581 FFA_ERROR_INVALID_PARAMETER); 582 } 583 584 spin_lock(&mbox->lock); 585 586 req = mbox->tx_buffer; 587 resp = mbox->rx_buffer; 588 buf_size = mbox->rxtx_page_count * FFA_PAGE_SIZE; 589 590 if (mbox->rxtx_page_count == 0U) { 591 WARN("%s: buffer pair not registered.\n", __func__); 592 ret = FFA_ERROR_INVALID_PARAMETER; 593 goto err_unlock_mailbox; 594 } 595 596 if (mbox->state != MAILBOX_STATE_EMPTY) { 597 WARN("%s: RX Buffer is full! %d\n", __func__, mbox->state); 598 ret = FFA_ERROR_DENIED; 599 goto err_unlock_mailbox; 600 } 601 602 if (fragment_length != total_length) { 603 WARN("%s: fragmented retrieve request not supported.\n", 604 __func__); 605 ret = FFA_ERROR_INVALID_PARAMETER; 606 goto err_unlock_mailbox; 607 } 608 609 if (req->emad_count == 0U) { 610 WARN("%s: unsupported attribute desc count %u.\n", 611 __func__, obj->desc.emad_count); 612 return -EINVAL; 613 } 614 615 if (total_length < sizeof(*req)) { 616 WARN("%s: invalid length %u < %zu\n", __func__, total_length, 617 sizeof(*req)); 618 ret = FFA_ERROR_INVALID_PARAMETER; 619 goto err_unlock_mailbox; 620 } 621 622 spin_lock(&spmc_shmem_obj_state.lock); 623 624 obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, req->handle); 625 if (obj == NULL) { 626 ret = FFA_ERROR_INVALID_PARAMETER; 627 goto err_unlock_all; 628 } 629 630 if (obj->desc_filled != obj->desc_size) { 631 WARN("%s: incomplete object desc filled %zu < size %zu\n", 632 __func__, obj->desc_filled, obj->desc_size); 633 ret = FFA_ERROR_INVALID_PARAMETER; 634 goto err_unlock_all; 635 } 636 637 if (req->emad_count != 0U && req->sender_id != obj->desc.sender_id) { 638 WARN("%s: wrong sender id 0x%x != 0x%x\n", 639 __func__, req->sender_id, obj->desc.sender_id); 640 ret = FFA_ERROR_INVALID_PARAMETER; 641 goto err_unlock_all; 642 } 643 644 if (req->emad_count != 0U && req->tag != obj->desc.tag) { 645 WARN("%s: wrong tag 0x%lx != 0x%lx\n", 646 __func__, req->tag, obj->desc.tag); 647 ret = FFA_ERROR_INVALID_PARAMETER; 648 goto err_unlock_all; 649 } 650 651 if (req->emad_count != 0U && req->emad_count != obj->desc.emad_count) { 652 WARN("%s: mistmatch of endpoint counts %u != %u\n", 653 __func__, req->emad_count, obj->desc.emad_count); 654 ret = FFA_ERROR_INVALID_PARAMETER; 655 goto err_unlock_all; 656 } 657 658 if (req->flags != 0U) { 659 if ((req->flags & FFA_MTD_FLAG_TYPE_MASK) != 660 (obj->desc.flags & FFA_MTD_FLAG_TYPE_MASK)) { 661 /* 662 * If the retrieve request specifies the memory 663 * transaction ensure it matches what we expect. 664 */ 665 WARN("%s: wrong mem transaction flags %x != %x\n", 666 __func__, req->flags, obj->desc.flags); 667 ret = FFA_ERROR_INVALID_PARAMETER; 668 goto err_unlock_all; 669 } 670 671 if (req->flags != FFA_MTD_FLAG_TYPE_SHARE_MEMORY && 672 req->flags != FFA_MTD_FLAG_TYPE_LEND_MEMORY) { 673 /* 674 * Current implementation does not support donate and 675 * it supports no other flags. 676 */ 677 WARN("%s: invalid flags 0x%x\n", __func__, req->flags); 678 ret = FFA_ERROR_INVALID_PARAMETER; 679 goto err_unlock_all; 680 } 681 } 682 683 /* 684 * Ensure the emad array lies within the bounds of the descriptor by 685 * checking the address of the element past the end of the array. 686 */ 687 if ((uintptr_t) &req->emad[req->emad_count] > 688 (uintptr_t)((uint8_t *) &req + total_length)) { 689 WARN("Invalid emad access.\n"); 690 return -EINVAL; 691 } 692 693 /* 694 * Validate all the endpoints match in the case of multiple 695 * borrowers. We don't mandate that the order of the borrowers 696 * must match in the descriptors therefore check to see if the 697 * endpoints match in any order. 698 */ 699 for (size_t i = 0; i < req->emad_count; i++) { 700 bool found = false; 701 702 for (size_t j = 0; j < obj->desc.emad_count; j++) { 703 if (req->emad[i].mapd.endpoint_id == 704 obj->desc.emad[j].mapd.endpoint_id) { 705 found = true; 706 break; 707 } 708 } 709 710 if (!found) { 711 WARN("%s: invalid receiver id (0x%x).\n", 712 __func__, req->emad[i].mapd.endpoint_id); 713 ret = FFA_ERROR_INVALID_PARAMETER; 714 goto err_unlock_all; 715 } 716 } 717 718 mbox->state = MAILBOX_STATE_FULL; 719 720 if (req->emad_count != 0U) { 721 obj->in_use++; 722 } 723 724 copy_size = MIN(obj->desc_size, buf_size); 725 726 memcpy(resp, &obj->desc, copy_size); 727 728 spin_unlock(&spmc_shmem_obj_state.lock); 729 spin_unlock(&mbox->lock); 730 731 SMC_RET8(handle, FFA_MEM_RETRIEVE_RESP, obj->desc_size, 732 copy_size, 0, 0, 0, 0, 0); 733 734 err_unlock_all: 735 spin_unlock(&spmc_shmem_obj_state.lock); 736 err_unlock_mailbox: 737 spin_unlock(&mbox->lock); 738 return spmc_ffa_error_return(handle, ret); 739 } 740 741 /** 742 * spmc_ffa_mem_frag_rx - FFA_MEM_FRAG_RX implementation. 743 * @client: Client state. 744 * @handle_low: Handle passed to &FFA_MEM_RETRIEVE_REQ. Bit[31:0]. 745 * @handle_high: Handle passed to &FFA_MEM_RETRIEVE_REQ. Bit[63:32]. 746 * @fragment_offset: Byte offset in descriptor to resume at. 747 * @sender_id: Bit[31:16]: Endpoint id of sender if client is a 748 * hypervisor. 0 otherwise. 749 * @smc_handle: Handle passed to smc call. Used to return 750 * FFA_MEM_FRAG_TX. 751 * 752 * Return: @smc_handle on success, error code on failure. 753 */ 754 long spmc_ffa_mem_frag_rx(uint32_t smc_fid, 755 bool secure_origin, 756 uint32_t handle_low, 757 uint32_t handle_high, 758 uint32_t fragment_offset, 759 uint32_t sender_id, 760 void *cookie, 761 void *handle, 762 uint64_t flags) 763 { 764 int ret; 765 void *src; 766 size_t buf_size; 767 size_t copy_size; 768 size_t full_copy_size; 769 uint32_t desc_sender_id; 770 struct mailbox *mbox = spmc_get_mbox_desc(secure_origin); 771 uint64_t mem_handle = handle_low | (((uint64_t)handle_high) << 32); 772 struct spmc_shmem_obj *obj; 773 774 if (!secure_origin) { 775 WARN("%s: can only be called from swld.\n", 776 __func__); 777 return spmc_ffa_error_return(handle, 778 FFA_ERROR_INVALID_PARAMETER); 779 } 780 781 spin_lock(&spmc_shmem_obj_state.lock); 782 783 obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, mem_handle); 784 if (obj == NULL) { 785 WARN("%s: invalid handle, 0x%lx, not a valid handle.\n", 786 __func__, mem_handle); 787 ret = FFA_ERROR_INVALID_PARAMETER; 788 goto err_unlock_shmem; 789 } 790 791 desc_sender_id = (uint32_t)obj->desc.sender_id << 16; 792 if (sender_id != 0U && sender_id != desc_sender_id) { 793 WARN("%s: invalid sender_id 0x%x != 0x%x\n", __func__, 794 sender_id, desc_sender_id); 795 ret = FFA_ERROR_INVALID_PARAMETER; 796 goto err_unlock_shmem; 797 } 798 799 if (fragment_offset >= obj->desc_size) { 800 WARN("%s: invalid fragment_offset 0x%x >= 0x%zx\n", 801 __func__, fragment_offset, obj->desc_size); 802 ret = FFA_ERROR_INVALID_PARAMETER; 803 goto err_unlock_shmem; 804 } 805 806 spin_lock(&mbox->lock); 807 808 if (mbox->rxtx_page_count == 0U) { 809 WARN("%s: buffer pair not registered.\n", __func__); 810 ret = FFA_ERROR_INVALID_PARAMETER; 811 goto err_unlock_all; 812 } 813 814 if (mbox->state != MAILBOX_STATE_EMPTY) { 815 WARN("%s: RX Buffer is full!\n", __func__); 816 ret = FFA_ERROR_DENIED; 817 goto err_unlock_all; 818 } 819 820 buf_size = mbox->rxtx_page_count * FFA_PAGE_SIZE; 821 822 mbox->state = MAILBOX_STATE_FULL; 823 824 full_copy_size = obj->desc_size - fragment_offset; 825 copy_size = MIN(full_copy_size, buf_size); 826 827 src = &obj->desc; 828 829 memcpy(mbox->rx_buffer, src + fragment_offset, copy_size); 830 831 spin_unlock(&mbox->lock); 832 spin_unlock(&spmc_shmem_obj_state.lock); 833 834 SMC_RET8(handle, FFA_MEM_FRAG_TX, handle_low, handle_high, 835 copy_size, sender_id, 0, 0, 0); 836 837 err_unlock_all: 838 spin_unlock(&mbox->lock); 839 err_unlock_shmem: 840 spin_unlock(&spmc_shmem_obj_state.lock); 841 return spmc_ffa_error_return(handle, ret); 842 } 843 844 /** 845 * spmc_ffa_mem_relinquish - FFA_MEM_RELINQUISH implementation. 846 * @client: Client state. 847 * 848 * Implements a subset of the FF-A FFA_MEM_RELINQUISH call. 849 * Used by secure os release previously shared memory to non-secure os. 850 * 851 * The handle to release must be in the client's (secure os's) transmit buffer. 852 * 853 * Return: 0 on success, error code on failure. 854 */ 855 int spmc_ffa_mem_relinquish(uint32_t smc_fid, 856 bool secure_origin, 857 uint32_t handle_low, 858 uint32_t handle_high, 859 uint32_t fragment_offset, 860 uint32_t sender_id, 861 void *cookie, 862 void *handle, 863 uint64_t flags) 864 { 865 int ret; 866 struct mailbox *mbox = spmc_get_mbox_desc(secure_origin); 867 struct spmc_shmem_obj *obj; 868 const struct ffa_mem_relinquish_descriptor *req; 869 870 if (!secure_origin) { 871 WARN("%s: unsupported relinquish direction.\n", __func__); 872 return spmc_ffa_error_return(handle, 873 FFA_ERROR_INVALID_PARAMETER); 874 } 875 876 spin_lock(&mbox->lock); 877 878 if (mbox->rxtx_page_count == 0U) { 879 WARN("%s: buffer pair not registered.\n", __func__); 880 ret = FFA_ERROR_INVALID_PARAMETER; 881 goto err_unlock_mailbox; 882 } 883 884 req = mbox->tx_buffer; 885 886 if (req->flags != 0U) { 887 WARN("%s: unsupported flags 0x%x\n", __func__, req->flags); 888 ret = FFA_ERROR_INVALID_PARAMETER; 889 goto err_unlock_mailbox; 890 } 891 892 if (req->endpoint_count == 0) { 893 WARN("%s: endpoint count cannot be 0.\n", __func__); 894 ret = FFA_ERROR_INVALID_PARAMETER; 895 goto err_unlock_mailbox; 896 } 897 898 spin_lock(&spmc_shmem_obj_state.lock); 899 900 obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, req->handle); 901 if (obj == NULL) { 902 ret = FFA_ERROR_INVALID_PARAMETER; 903 goto err_unlock_all; 904 } 905 906 if (obj->desc.emad_count != req->endpoint_count) { 907 WARN("%s: mismatch of endpoint count %u != %u\n", __func__, 908 obj->desc.emad_count, req->endpoint_count); 909 ret = FFA_ERROR_INVALID_PARAMETER; 910 goto err_unlock_all; 911 } 912 913 /* Validate requested endpoint IDs match descriptor. */ 914 for (size_t i = 0; i < req->endpoint_count; i++) { 915 bool found = false; 916 917 for (unsigned int j = 0; j < obj->desc.emad_count; j++) { 918 if (req->endpoint_array[i] == 919 obj->desc.emad[j].mapd.endpoint_id) { 920 found = true; 921 break; 922 } 923 } 924 925 if (!found) { 926 WARN("%s: Invalid endpoint ID (0x%x).\n", 927 __func__, req->endpoint_array[i]); 928 ret = FFA_ERROR_INVALID_PARAMETER; 929 goto err_unlock_all; 930 } 931 } 932 933 if (obj->in_use == 0U) { 934 ret = FFA_ERROR_INVALID_PARAMETER; 935 goto err_unlock_all; 936 } 937 obj->in_use--; 938 939 spin_unlock(&spmc_shmem_obj_state.lock); 940 spin_unlock(&mbox->lock); 941 942 SMC_RET1(handle, FFA_SUCCESS_SMC32); 943 944 err_unlock_all: 945 spin_unlock(&spmc_shmem_obj_state.lock); 946 err_unlock_mailbox: 947 spin_unlock(&mbox->lock); 948 return spmc_ffa_error_return(handle, ret); 949 } 950 951 /** 952 * spmc_ffa_mem_reclaim - FFA_MEM_RECLAIM implementation. 953 * @client: Client state. 954 * @handle_low: Unique handle of shared memory object to reclaim. Bit[31:0]. 955 * @handle_high: Unique handle of shared memory object to reclaim. 956 * Bit[63:32]. 957 * @flags: Unsupported, ignored. 958 * 959 * Implements a subset of the FF-A FFA_MEM_RECLAIM call. 960 * Used by non-secure os reclaim memory previously shared with secure os. 961 * 962 * Return: 0 on success, error code on failure. 963 */ 964 int spmc_ffa_mem_reclaim(uint32_t smc_fid, 965 bool secure_origin, 966 uint32_t handle_low, 967 uint32_t handle_high, 968 uint32_t mem_flags, 969 uint64_t x4, 970 void *cookie, 971 void *handle, 972 uint64_t flags) 973 { 974 int ret; 975 struct spmc_shmem_obj *obj; 976 uint64_t mem_handle = handle_low | (((uint64_t)handle_high) << 32); 977 978 if (secure_origin) { 979 WARN("%s: unsupported reclaim direction.\n", __func__); 980 return spmc_ffa_error_return(handle, 981 FFA_ERROR_INVALID_PARAMETER); 982 } 983 984 if (mem_flags != 0U) { 985 WARN("%s: unsupported flags 0x%x\n", __func__, mem_flags); 986 return spmc_ffa_error_return(handle, 987 FFA_ERROR_INVALID_PARAMETER); 988 } 989 990 spin_lock(&spmc_shmem_obj_state.lock); 991 992 obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, mem_handle); 993 if (obj == NULL) { 994 ret = FFA_ERROR_INVALID_PARAMETER; 995 goto err_unlock; 996 } 997 if (obj->in_use != 0U) { 998 ret = FFA_ERROR_DENIED; 999 goto err_unlock; 1000 } 1001 spmc_shmem_obj_free(&spmc_shmem_obj_state, obj); 1002 spin_unlock(&spmc_shmem_obj_state.lock); 1003 1004 SMC_RET1(handle, FFA_SUCCESS_SMC32); 1005 1006 err_unlock: 1007 spin_unlock(&spmc_shmem_obj_state.lock); 1008 return spmc_ffa_error_return(handle, ret); 1009 } 1010