Align stacks to page boundaries.

Page alignment supersedes the previous alignment that was a requirement
of aarch64. It also ensures cache lines don't contain data other than
the stack which could be accessed from other cores.

Change-Id: I3a9eca651e52062c93d8e6b3278e158a65f1c1f5
diff --git a/src/arch/aarch64/inc/hf/arch/types.h b/src/arch/aarch64/inc/hf/arch/types.h
index 25d3e0c..34beb15 100644
--- a/src/arch/aarch64/inc/hf/arch/types.h
+++ b/src/arch/aarch64/inc/hf/arch/types.h
@@ -24,6 +24,7 @@
 
 #define PAGE_BITS 12
 #define PAGE_LEVEL_BITS 9
+#define STACK_ALIGN 16
 #define FLOAT_REG_BYTES 16
 #define NUM_GP_REGS 31
 
diff --git a/src/arch/fake/inc/hf/arch/types.h b/src/arch/fake/inc/hf/arch/types.h
index bcf33f3..8a0eccb 100644
--- a/src/arch/fake/inc/hf/arch/types.h
+++ b/src/arch/fake/inc/hf/arch/types.h
@@ -21,6 +21,7 @@
 
 #define PAGE_BITS 12
 #define PAGE_LEVEL_BITS 9
+#define STACK_ALIGN 64
 
 /** The type of a page table entry (PTE). */
 typedef uint64_t pte_t;
diff --git a/src/cpu.c b/src/cpu.c
index ea66af2..823826c 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -31,8 +31,20 @@
 
 #define STACK_SIZE PAGE_SIZE
 
-/* The stack to be used by the CPUs. */
-alignas(2 * sizeof(uintreg_t)) static char callstacks[MAX_CPUS][STACK_SIZE];
+/**
+ * The stacks to be used by the CPUs.
+ *
+ * Align to page boundaries to ensure that cache lines are not shared between a
+ * CPU's stack and data that can be accessed from other CPUs. If this did
+ * happen, there may be coherency problems when the stack is being used before
+ * caching is enabled.
+ */
+alignas(PAGE_SIZE) static char callstacks[MAX_CPUS][STACK_SIZE];
+
+/* NOLINTNEXTLINE(misc-redundant-expression) */
+static_assert((STACK_SIZE % PAGE_SIZE) == 0, "Keep each stack page aligned.");
+static_assert((PAGE_SIZE % STACK_ALIGN) == 0,
+	      "Page alignment is too weak for the stack.");
 
 /**
  * Internal buffer used to store SPCI messages from a VM Tx. Its usage prevents