Merge changes Ic58f4966,Ib7b438b8,I400f0f1f into integration

* changes:
  refactor(el3-spmc): add comments
  refactor(el3-spmc): move checks after loop
  refactor(el3-spmc): validate alignment earlier
diff --git a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
index 8183a0a..15c7e91 100644
--- a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
+++ b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
@@ -777,10 +777,16 @@
 static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
 				uint32_t ffa_version)
 {
+	uint64_t total_page_count;
 	const struct ffa_emad_v1_0 *first_emad;
 	const struct ffa_emad_v1_0 *end_emad;
 	size_t emad_size;
 	uint32_t comp_mrd_offset = 0;
+	size_t header_emad_size;
+	size_t size;
+	size_t count;
+	size_t expected_size;
+	struct ffa_comp_mrd *comp;
 
 	if (obj->desc_filled != obj->desc_size) {
 		ERROR("BUG: %s called on incomplete object (%zu != %zu)\n",
@@ -798,22 +804,14 @@
 	first_emad = spmc_shmem_obj_get_emad(&obj->desc, 0,
 					     ffa_version, &emad_size);
 	end_emad = emad_advance(first_emad, obj->desc.emad_count * emad_size);
+	comp_mrd_offset = first_emad->comp_mrd_offset;
 
 	/* Loop through the endpoint descriptors, validating each of them. */
 	for (const struct ffa_emad_v1_0 *emad = first_emad;
 	     emad < end_emad;
 	     emad = emad_advance(emad, emad_size)) {
-		size_t size;
-		size_t count;
-		size_t expected_size;
-		uint64_t total_page_count;
-		size_t header_emad_size;
-		uint32_t offset;
-		struct ffa_comp_mrd *comp;
 		ffa_endpoint_id16_t ep_id;
 
-		offset = emad->comp_mrd_offset;
-
 		/*
 		 * If a partition ID resides in the secure world validate that
 		 * the partition ID is for a known partition. Ignore any
@@ -831,82 +829,85 @@
 
 		/*
 		 * The offset provided to the composite memory region descriptor
-		 * should be consistent across endpoint descriptors. Store the
-		 * first entry and compare against subsequent entries.
+		 * should be consistent across endpoint descriptors.
 		 */
-		if (comp_mrd_offset == 0) {
-			comp_mrd_offset = offset;
-		} else {
-			if (comp_mrd_offset != offset) {
-				ERROR("%s: mismatching offsets provided, %u != %u\n",
-				       __func__, offset, comp_mrd_offset);
-				return FFA_ERROR_INVALID_PARAMETER;
-			}
-			continue; /* Remainder only executed on first iteration. */
+		if (comp_mrd_offset != emad->comp_mrd_offset) {
+			ERROR("%s: mismatching offsets provided, %u != %u\n",
+			       __func__, emad->comp_mrd_offset, comp_mrd_offset);
+			return FFA_ERROR_INVALID_PARAMETER;
 		}
+	}
 
-		header_emad_size = (size_t)((uint8_t *)emad - (uint8_t *)&obj->desc) +
-			(obj->desc.emad_count * emad_size);
+	header_emad_size = (size_t)((const uint8_t *)end_emad -
+				    (const uint8_t *)&obj->desc);
 
-		if (offset < header_emad_size) {
-			WARN("%s: invalid object, offset %u < header + emad %zu\n",
-			     __func__, offset, header_emad_size);
-			return FFA_ERROR_INVALID_PARAMETER;
-		}
+	/*
+	 * Check that the composite descriptor
+	 * is after the endpoint descriptors.
+	 */
+	if (comp_mrd_offset < header_emad_size) {
+		WARN("%s: invalid object, offset %u < header + emad %zu\n",
+		     __func__, comp_mrd_offset, header_emad_size);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
 
-		size = obj->desc_size;
+	/* Ensure the composite descriptor offset is aligned. */
+	if (!is_aligned(comp_mrd_offset, 16)) {
+		WARN("%s: invalid object, unaligned composite memory "
+		     "region descriptor offset %u.\n",
+		     __func__, comp_mrd_offset);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
 
-		if (offset > size) {
-			WARN("%s: invalid object, offset %u > total size %zu\n",
-			     __func__, offset, obj->desc_size);
-			return FFA_ERROR_INVALID_PARAMETER;
-		}
-		size -= offset;
+	size = obj->desc_size;
 
-		if (size < sizeof(struct ffa_comp_mrd)) {
-			WARN("%s: invalid object, offset %u, total size %zu, no header space.\n",
-			     __func__, offset, obj->desc_size);
-			return FFA_ERROR_INVALID_PARAMETER;
-		}
-		size -= sizeof(struct ffa_comp_mrd);
+	/* Check that the composite descriptor is in bounds. */
+	if (comp_mrd_offset > size) {
+		WARN("%s: invalid object, offset %u > total size %zu\n",
+		     __func__, comp_mrd_offset, obj->desc_size);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
+	size -= comp_mrd_offset;
 
-		count = size / sizeof(struct ffa_cons_mrd);
+	if (size < sizeof(struct ffa_comp_mrd)) {
+		WARN("%s: invalid object, offset %u, total size %zu, no header space.\n",
+		     __func__, comp_mrd_offset, obj->desc_size);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
+	size -= sizeof(struct ffa_comp_mrd);
 
-		comp = spmc_shmem_obj_get_comp_mrd(obj, ffa_version);
+	count = size / sizeof(struct ffa_cons_mrd);
 
-		if (comp == NULL) {
-			WARN("%s: invalid comp_mrd offset\n", __func__);
-			return FFA_ERROR_INVALID_PARAMETER;
-		}
+	comp = spmc_shmem_obj_get_comp_mrd(obj, ffa_version);
 
-		if (comp->address_range_count != count) {
-			WARN("%s: invalid object, desc count %u != %zu\n",
-			     __func__, comp->address_range_count, count);
-			return FFA_ERROR_INVALID_PARAMETER;
-		}
+	if (comp->address_range_count != count) {
+		WARN("%s: invalid object, desc count %u != %zu\n",
+		     __func__, comp->address_range_count, count);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
 
-		expected_size = offset + sizeof(*comp) +
-			count * sizeof(struct ffa_cons_mrd);
+	expected_size = comp_mrd_offset + sizeof(*comp) +
+		count * sizeof(struct ffa_cons_mrd);
 
-		if (expected_size != obj->desc_size) {
-			WARN("%s: invalid object, computed size %zu != size %zu\n",
-			       __func__, expected_size, obj->desc_size);
-			return FFA_ERROR_INVALID_PARAMETER;
-		}
+	if (expected_size != obj->desc_size) {
+		WARN("%s: invalid object, computed size %zu != size %zu\n",
+		       __func__, expected_size, obj->desc_size);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
 
-		total_page_count = 0;
+	total_page_count = 0;
 
-		for (size_t i = 0; i < count; i++) {
-			total_page_count +=
-				comp->address_range_array[i].page_count;
-		}
-		if (comp->total_page_count != total_page_count) {
-			WARN("%s: invalid object, desc total_page_count %u != %" PRIu64 "\n",
-			     __func__, comp->total_page_count,
-			total_page_count);
-			return FFA_ERROR_INVALID_PARAMETER;
-		}
+	for (size_t i = 0; i < count; i++) {
+		total_page_count +=
+			comp->address_range_array[i].page_count;
 	}
+	if (comp->total_page_count != total_page_count) {
+		WARN("%s: invalid object, desc total_page_count %u != %" PRIu64 "\n",
+		     __func__, comp->total_page_count,
+		total_page_count);
+		return FFA_ERROR_INVALID_PARAMETER;
+	}
+
 	return 0;
 }