refactor(memory share): init descriptor for memory retrieve
Made the ffa_memory_retrieve_request_init be capable of initializing
the memory region descriptor with multiple receivers.
Kept an initialization function for tests with a single receiver,
to avoid having to refactor most tests.
Change-Id: I1eecae52ede91a93b03a2772cc1791cc9bf05165
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/inc/vmapi/hf/ffa.h b/inc/vmapi/hf/ffa.h
index 9e97684..e30821d 100644
--- a/inc/vmapi/hf/ffa.h
+++ b/inc/vmapi/hf/ffa.h
@@ -987,6 +987,12 @@
uint32_t *total_length);
uint32_t ffa_memory_retrieve_request_init(
struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
+ ffa_vm_id_t sender, struct ffa_memory_access receivers[],
+ uint32_t receiver_count, uint32_t tag, ffa_memory_region_flags_t flags,
+ enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
+ enum ffa_memory_shareability shareability);
+uint32_t ffa_memory_retrieve_request_init_single_receiver(
+ struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
ffa_vm_id_t sender, ffa_vm_id_t receiver, uint32_t tag,
ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
enum ffa_instruction_access instruction_access,
diff --git a/test/vmapi/common/ffa.c b/test/vmapi/common/ffa.c
index 42b0e48..76f6f23 100644
--- a/test/vmapi/common/ffa.c
+++ b/test/vmapi/common/ffa.c
@@ -130,7 +130,7 @@
* Send the appropriate retrieve request to the VM so that it can use it
* to retrieve the memory.
*/
- msg_size = ffa_memory_retrieve_request_init(
+ msg_size = ffa_memory_retrieve_request_init_single_receiver(
tx_buffer, handle, sender, recipient, 0, retrieve_flags,
retrieve_data_access, retrieve_instruction_access,
FFA_MEMORY_NORMAL_MEM, FFA_MEMORY_CACHE_WRITE_BACK,
@@ -212,7 +212,7 @@
* Send the appropriate retrieve request to the VM so that it can use it
* to retrieve the memory.
*/
- msg_size = ffa_memory_retrieve_request_init(
+ msg_size = ffa_memory_retrieve_request_init_single_receiver(
tx_buffer, handle, sender, recipient, 0, 0,
retrieve_data_access, retrieve_instruction_access,
FFA_MEMORY_NORMAL_MEM, FFA_MEMORY_CACHE_WRITE_BACK,
diff --git a/test/vmapi/el0_partitions/memory_sharing.c b/test/vmapi/el0_partitions/memory_sharing.c
index 65775fc..6a84137 100644
--- a/test/vmapi/el0_partitions/memory_sharing.c
+++ b/test/vmapi/el0_partitions/memory_sharing.c
@@ -2250,7 +2250,7 @@
handle = ffa_mem_success_handle(ret);
- msg_size = ffa_memory_retrieve_request_init(
+ msg_size = ffa_memory_retrieve_request_init_single_receiver(
mb.send, handle, HF_PRIMARY_VM_ID, SERVICE_VM1, 0,
0xFFFFFFFF, FFA_DATA_ACCESS_RW,
FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
@@ -2331,13 +2331,16 @@
handle = ffa_mem_success_handle(ret);
for (uint32_t j = 0; j < ARRAY_SIZE(invalid_attributes); ++j) {
- msg_size = ffa_memory_retrieve_request_init(
- mb.send, handle, HF_PRIMARY_VM_ID, SERVICE_VM1,
- 0, 0, FFA_DATA_ACCESS_RW,
- FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
- invalid_attributes[j].memory_type,
- invalid_attributes[j].memory_cacheability,
- invalid_attributes[j].memory_shareability);
+ msg_size =
+ ffa_memory_retrieve_request_init_single_receiver(
+ mb.send, handle, HF_PRIMARY_VM_ID,
+ SERVICE_VM1, 0, 0, FFA_DATA_ACCESS_RW,
+ FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
+ invalid_attributes[j].memory_type,
+ invalid_attributes[j]
+ .memory_cacheability,
+ invalid_attributes[j]
+ .memory_shareability);
EXPECT_LE(msg_size, HF_MAILBOX_SIZE);
@@ -2406,7 +2409,7 @@
handle = ffa_mem_success_handle(ret);
/* Prepare retrieve request setting clear memory flags. */
- msg_size = ffa_memory_retrieve_request_init(
+ msg_size = ffa_memory_retrieve_request_init_single_receiver(
mb.send, handle, HF_PRIMARY_VM_ID, SERVICE_VM1, 0,
FFA_MEMORY_REGION_FLAG_CLEAR |
FFA_MEMORY_REGION_FLAG_CLEAR_RELINQUISH,
@@ -2462,7 +2465,7 @@
* Prepare retrieve request with RO, and setting flag to clear memory.
* Should fail at the receiver's FFA_MEM_RETRIEVE call.
*/
- msg_size = ffa_memory_retrieve_request_init(
+ msg_size = ffa_memory_retrieve_request_init_single_receiver(
mb.send, handle, HF_PRIMARY_VM_ID, SERVICE_VM1, 0,
FFA_MEMORY_REGION_FLAG_CLEAR, FFA_DATA_ACCESS_RO,
FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED, FFA_MEMORY_NORMAL_MEM,
diff --git a/test/vmapi/primary_with_secondaries/memory_sharing.c b/test/vmapi/primary_with_secondaries/memory_sharing.c
index 27d3997..0592f8e 100644
--- a/test/vmapi/primary_with_secondaries/memory_sharing.c
+++ b/test/vmapi/primary_with_secondaries/memory_sharing.c
@@ -372,7 +372,7 @@
* to retrieve the memory.
* The retrieve request doesn't specify the memory type.
*/
- msg_size = ffa_memory_retrieve_request_init(
+ msg_size = ffa_memory_retrieve_request_init_single_receiver(
mb.send, handle, HF_PRIMARY_VM_ID, SERVICE_VM1, 0, 0,
FFA_DATA_ACCESS_RW, FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
FFA_MEMORY_NOT_SPECIFIED_MEM, 0, 0);
@@ -2357,13 +2357,15 @@
handle = ffa_mem_success_handle(ret);
for (unsigned int j = 0; j < ARRAY_SIZE(invalid_flags); ++j) {
- msg_size = ffa_memory_retrieve_request_init(
- mb.send, handle, HF_PRIMARY_VM_ID, SERVICE_VM1,
- 0, invalid_flags[j], FFA_DATA_ACCESS_RW,
- FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
- FFA_MEMORY_NORMAL_MEM,
- FFA_MEMORY_CACHE_WRITE_BACK,
- FFA_MEMORY_INNER_SHAREABLE);
+ msg_size =
+ ffa_memory_retrieve_request_init_single_receiver(
+ mb.send, handle, HF_PRIMARY_VM_ID,
+ SERVICE_VM1, 0, invalid_flags[j],
+ FFA_DATA_ACCESS_RW,
+ FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
+ FFA_MEMORY_NORMAL_MEM,
+ FFA_MEMORY_CACHE_WRITE_BACK,
+ FFA_MEMORY_INNER_SHAREABLE);
EXPECT_LE(msg_size, HF_MAILBOX_SIZE);
@@ -2440,13 +2442,16 @@
handle = ffa_mem_success_handle(ret);
for (uint32_t j = 0; j < ARRAY_SIZE(invalid_attributes); ++j) {
- msg_size = ffa_memory_retrieve_request_init(
- mb.send, handle, HF_PRIMARY_VM_ID, SERVICE_VM1,
- 0, 0, FFA_DATA_ACCESS_RW,
- FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
- invalid_attributes[j].memory_type,
- invalid_attributes[j].memory_cacheability,
- invalid_attributes[j].memory_shareability);
+ msg_size =
+ ffa_memory_retrieve_request_init_single_receiver(
+ mb.send, handle, HF_PRIMARY_VM_ID,
+ SERVICE_VM1, 0, 0, FFA_DATA_ACCESS_RW,
+ FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
+ invalid_attributes[j].memory_type,
+ invalid_attributes[j]
+ .memory_cacheability,
+ invalid_attributes[j]
+ .memory_shareability);
EXPECT_LE(msg_size, HF_MAILBOX_SIZE);
@@ -2515,7 +2520,7 @@
handle = ffa_mem_success_handle(ret);
/* Prepare retrieve request setting clear memory flags. */
- msg_size = ffa_memory_retrieve_request_init(
+ msg_size = ffa_memory_retrieve_request_init_single_receiver(
mb.send, handle, HF_PRIMARY_VM_ID, SERVICE_VM1, 0,
FFA_MEMORY_REGION_FLAG_CLEAR |
FFA_MEMORY_REGION_FLAG_CLEAR_RELINQUISH,
@@ -2571,7 +2576,7 @@
* Prepare retrieve request with RO, and setting flag to clear memory.
* Should fail at the receiver's FFA_MEM_RETRIEVE call.
*/
- msg_size = ffa_memory_retrieve_request_init(
+ msg_size = ffa_memory_retrieve_request_init_single_receiver(
mb.send, handle, HF_PRIMARY_VM_ID, SERVICE_VM1, 0,
FFA_MEMORY_REGION_FLAG_CLEAR, FFA_DATA_ACCESS_RO,
FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED, FFA_MEMORY_NORMAL_MEM,
@@ -2639,7 +2644,7 @@
* memory. Should fail at the receiver's FFA_MEM_RETRIEVE_REQ
* call with FFA_DENIED.
*/
- msg_size = ffa_memory_retrieve_request_init(
+ msg_size = ffa_memory_retrieve_request_init_single_receiver(
mb.send, handle, HF_PRIMARY_VM_ID, SERVICE_VM1, 0,
FFA_MEMORY_REGION_FLAG_CLEAR, FFA_DATA_ACCESS_RW,
/* Different args for lend and donate. */
@@ -2715,7 +2720,7 @@
* Should fail at the receiver's FFA_MEM_RETRIEVE_REQ
* call with FFA_INVALID_PARAMETERS.
*/
- msg_size = ffa_memory_retrieve_request_init(
+ msg_size = ffa_memory_retrieve_request_init_single_receiver(
mb.send, handle, HF_PRIMARY_VM_ID, SERVICE_VM1, 0,
send_function[i] == ffa_mem_share
? FFA_MEMORY_REGION_TRANSACTION_TYPE_LEND
diff --git a/vmlib/ffa.c b/vmlib/ffa.c
index 69ce8b2..51e8b87 100644
--- a/vmlib/ffa.c
+++ b/vmlib/ffa.c
@@ -228,7 +228,7 @@
*
* Returns the size of the message written.
*/
-uint32_t ffa_memory_retrieve_request_init(
+uint32_t ffa_memory_retrieve_request_init_single_receiver(
struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
ffa_vm_id_t sender, ffa_vm_id_t receiver, uint32_t tag,
ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
@@ -236,7 +236,25 @@
enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
enum ffa_memory_shareability shareability)
{
+ struct ffa_memory_access receiver_permissions;
+
+ ffa_memory_access_init_permissions(&receiver_permissions, receiver,
+ data_access, instruction_access, 0);
+
+ return ffa_memory_retrieve_request_init(
+ memory_region, handle, sender, &receiver_permissions, 1, tag,
+ flags, type, cacheability, shareability);
+}
+
+uint32_t ffa_memory_retrieve_request_init(
+ struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
+ ffa_vm_id_t sender, struct ffa_memory_access receivers[],
+ uint32_t receiver_count, uint32_t tag, ffa_memory_region_flags_t flags,
+ enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
+ enum ffa_memory_shareability shareability)
+{
ffa_memory_attributes_t attributes = 0;
+ uint32_t i;
/* Set memory region's page attributes. */
ffa_set_memory_type_attr(&attributes, type);
@@ -244,18 +262,20 @@
ffa_set_memory_shareability_attr(&attributes, shareability);
ffa_memory_region_init_header(memory_region, sender, attributes, flags,
- handle, tag, 1);
- ffa_memory_access_init_permissions(&memory_region->receivers[0],
- receiver, data_access,
- instruction_access, 0);
+ handle, tag, receiver_count);
- /*
- * Offset 0 in this case means that the hypervisor should allocate the
- * address ranges. This is the only configuration supported by Hafnium,
- * as it enforces 1:1 mappings in the stage 2 page tables.
- */
- memory_region->receivers[0].composite_memory_region_offset = 0;
- memory_region->receivers[0].reserved_0 = 0;
+#if defined(__linux__) && defined(__KERNEL__)
+ memcpy(memory_region->receivers, receivers,
+ receiver_count * sizeof(struct ffa_memory_access));
+#else
+ memcpy_s(memory_region->receivers,
+ MAX_MEM_SHARE_RECIPIENTS * sizeof(struct ffa_memory_access),
+ receivers, receiver_count * sizeof(struct ffa_memory_access));
+#endif
+ /* Zero the composite offset for all receivers */
+ for (i = 0U; i < receiver_count; i++) {
+ memory_region->receivers[i].composite_memory_region_offset = 0U;
+ }
return sizeof(struct ffa_memory_region) +
memory_region->receiver_count * sizeof(struct ffa_memory_access);