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);