Ensure that SPCI memory region constituents are aligned.

Misalignment was causing test failures on FVP.

Bug: 143755046
Change-Id: I0d55e43f9f07fb18d4b372f5625273f09def92e7
diff --git a/inc/vmapi/hf/spci.h b/inc/vmapi/hf/spci.h
index 1c3ae01..b00fb46 100644
--- a/inc/vmapi/hf/spci.h
+++ b/inc/vmapi/hf/spci.h
@@ -18,6 +18,14 @@
 
 #include "hf/types.h"
 
+/*
+ * Copied from hf/arch/std.h because we can't include Hafnium internal headers
+ * here.
+ */
+#ifndef align_up
+#define align_up(v, a) (((uintptr_t)(v) + (a - 1)) & ~(a - 1))
+#endif
+
 /* clang-format off */
 
 #define SPCI_LOW_32_ID  0x84000060
@@ -372,10 +380,15 @@
 	memory_region->attributes[0].receiver = receiver;
 	memory_region->attributes[0].memory_attributes = attributes;
 
-	memory_region->constituent_offset =
+	/*
+	 * Constituent offset must be aligned to a 64-bit boundary so that
+	 * 64-bit addresses can be copied without alignment faults.
+	 */
+	memory_region->constituent_offset = align_up(
 		sizeof(struct spci_memory_region) +
-		memory_region->attribute_count *
-			sizeof(struct spci_memory_region_attributes);
+			memory_region->attribute_count *
+				sizeof(struct spci_memory_region_attributes),
+		8);
 	region_constituents =
 		spci_memory_region_get_constituents(memory_region);
 
diff --git a/src/api.c b/src/api.c
index bdade61..caf024c 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1493,6 +1493,15 @@
 
 	size_t size;
 
+	/*
+	 * Make sure constituents are properly aligned to a 64-bit boundary. If
+	 * not we would get alignment faults trying to read (64-bit) page
+	 * addresses.
+	 */
+	if (!is_aligned(constituents, 8)) {
+		return spci_error(SPCI_INVALID_PARAMETERS);
+	}
+
 	/* Disallow reflexive shares as this suggests an error in the VM. */
 	if (to == from) {
 		return spci_error(SPCI_INVALID_PARAMETERS);