fix(memory share): Flags from mem region MBZ
According to the FF-A specification, the flags field from the memory
transaction descriptor is used to govern the behavior in a memory
management transaction, and in some cases some bits Must Be Zero (MBZ).
This patch adds proper checks to the 'ffa_memory_region' when handling
the memory sharing interfaces, so that error is returned when the bits
that MBZ aren't.
Change-Id: If5de9bb25d263b01a21e3c7d71bac707ab8652d5
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/src/api.c b/src/api.c
index 82619e0..d13e3ae 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2052,6 +2052,36 @@
return (struct ffa_value){.func = FFA_INTERRUPT_32};
}
+static bool api_memory_region_check_flags(
+ struct ffa_memory_region *memory_region, uint32_t share_func)
+{
+ switch (share_func) {
+ case FFA_MEM_SHARE_32:
+ if ((memory_region->flags & FFA_MEMORY_REGION_FLAG_CLEAR) !=
+ 0U) {
+ return false;
+ }
+ /* Intentional fall-through */
+ case FFA_MEM_LEND_32:
+ case FFA_MEM_DONATE_32: {
+ /* Bits 31:2 Must Be Zero. */
+ ffa_memory_receiver_flags_t to_mask =
+ ~(FFA_MEMORY_REGION_FLAG_CLEAR |
+ FFA_MEMORY_REGION_FLAG_TIME_SLICE);
+
+ if ((memory_region->flags & to_mask) != 0U) {
+ return false;
+ }
+ break;
+ }
+ default:
+ panic("Check for mem send calls only.\n");
+ }
+
+ /* Last check reserved values are 0 */
+ return true;
+}
+
struct ffa_value api_ffa_mem_send(uint32_t share_func, uint32_t length,
uint32_t fragment_length, ipaddr_t address,
uint32_t page_count, struct vcpu *current)
@@ -2124,6 +2154,13 @@
goto out;
}
+ if (!api_memory_region_check_flags(memory_region, share_func)) {
+ dlog_verbose(
+ "Memory region reserved arguments must be zero.\n");
+ ret = ffa_error(FFA_INVALID_PARAMETERS);
+ goto out;
+ }
+
if (memory_region->receiver_count != 1) {
/* Hafnium doesn't support multi-way memory sharing for now. */
dlog_verbose(