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(