fix(ffa): add check for 'Address Range Alignemnt Hint'
FFA_MEM_RETRIEVE_REQ ABI defines a 'Address Range Alignment Hint'
which is curently not supported by Hafnium.
Adding a check to ensure the field is 0, returning
FFA_INVALID_PARAMETERS otherwise.
Improving the already existing `ffa_validate_retrieve_req_mbz` unit
test to take into account this field as well.
Change-Id: I1827b929c7b5a26cd874b5984c7de198f1d6be25
Signed-off-by: Federico Recanati <federico.recanati@arm.com>
diff --git a/inc/vmapi/hf/ffa.h b/inc/vmapi/hf/ffa.h
index 82c742e..e7a626c 100644
--- a/inc/vmapi/hf/ffa.h
+++ b/inc/vmapi/hf/ffa.h
@@ -616,6 +616,9 @@
#define FFA_MEMORY_REGION_TRANSACTION_TYPE_LEND ((0x2U) << 3)
#define FFA_MEMORY_REGION_TRANSACTION_TYPE_DONATE ((0x3U) << 3)
+#define FFA_MEMORY_REGION_ADDRESS_RANGE_HINT_VALID ((0x1U) << 9)
+#define FFA_MEMORY_REGION_ADDRESS_RANGE_HINT_MASK ((0xFU) << 5)
+
/**
* This corresponds to table 42 of the FF-A 1.0 EAC specification, "Endpoint
* memory access descriptor".
diff --git a/src/ffa_memory.c b/src/ffa_memory.c
index f51bbd8..d68636c 100644
--- a/src/ffa_memory.c
+++ b/src/ffa_memory.c
@@ -1460,6 +1460,7 @@
*permissions);
return ffa_error(FFA_INVALID_PARAMETERS);
}
+
if (share_func == FFA_MEM_DONATE_32 &&
data_access != FFA_DATA_ACCESS_NOT_SPECIFIED) {
dlog_verbose(
@@ -2250,6 +2251,23 @@
goto out;
}
+ if ((retrieve_request->flags &
+ FFA_MEMORY_REGION_ADDRESS_RANGE_HINT_VALID) != 0) {
+ dlog_verbose(
+ "Retriever specified 'address range alignment hint'"
+ " not supported.\n");
+ ret = ffa_error(FFA_INVALID_PARAMETERS);
+ goto out;
+ }
+ if ((retrieve_request->flags &
+ FFA_MEMORY_REGION_ADDRESS_RANGE_HINT_MASK) != 0) {
+ dlog_verbose(
+ "Bits 8-5 must be zero in memory region's flags "
+ "(address range alignment hint not supported).\n");
+ ret = ffa_error(FFA_INVALID_PARAMETERS);
+ goto out;
+ }
+
if ((retrieve_request->flags & ~0x7FF) != 0U) {
dlog_verbose(
"Bits 31-10 must be zero in memory region's flags.\n");
diff --git a/test/vmapi/primary_with_secondaries/memory_sharing.c b/test/vmapi/primary_with_secondaries/memory_sharing.c
index c8de2bc..66b9b5e 100644
--- a/test/vmapi/primary_with_secondaries/memory_sharing.c
+++ b/test/vmapi/primary_with_secondaries/memory_sharing.c
@@ -2192,6 +2192,13 @@
SERVICE_SELECT(SERVICE_VM1, "ffa_memory_share_fail_invalid_parameters",
mb.send);
+ unsigned invalid_flags[] = {
+ 0xFFFFFFFF, /* Incorrect transaction type [4:3]*/
+ 0xFFFFFFE0, /* Unsupported address range limit hint [9] */
+ 0xFFFFFDE0, /* [8:5] MBZ when not asking for address range */
+ 0xFFFFFC00 /* [31:10] MBZ */
+ };
+
for (unsigned int i = 0; i < ARRAY_SIZE(send_function); i++) {
/* Prepare memory region, and set all flags */
EXPECT_EQ(ffa_memory_region_init(
@@ -2210,21 +2217,24 @@
handle = ffa_mem_success_handle(ret);
- msg_size = ffa_memory_retrieve_request_init(
- mb.send, handle, HF_PRIMARY_VM_ID, SERVICE_VM1, 0,
- 0xFFFFFFFF, FFA_DATA_ACCESS_RW,
- FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
- FFA_MEMORY_NORMAL_MEM, FFA_MEMORY_CACHE_WRITE_BACK,
- FFA_MEMORY_INNER_SHAREABLE);
+ 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);
- EXPECT_LE(msg_size, HF_MAILBOX_SIZE);
+ EXPECT_LE(msg_size, HF_MAILBOX_SIZE);
- EXPECT_EQ(
- ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size, 0)
- .func,
- FFA_SUCCESS_32);
+ EXPECT_EQ(ffa_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1,
+ msg_size, 0)
+ .func,
+ FFA_SUCCESS_32);
- ffa_run(SERVICE_VM1, 0);
+ ffa_run(SERVICE_VM1, 0);
+ }
EXPECT_EQ(ffa_mem_reclaim(handle, 0).func, FFA_SUCCESS_32);
}