fix(VHE): Fix Instr/Data abort handling for EL0

This patch fixes instruction abort handling for EL0 partitions. When
there is an instruction abort on a writeable page, the partition must
not be resumed since SCTLR_WXN bit is set, making any writeable page not
executable. This is however fixed in architecture agnostic code since
WXN is common across most architectures.
This patch also fixes data abort handling on unaligned accesses, on
AArch64. This cannot be fixed in architecture agnostic code since the
syndrome for unaligned accesses vary by architecture.

Signed-off-by: Raghu Krishnamurthy <raghu.ncstate@gmail.com>
Change-Id: I4d7c0ba34c5dedcf1b9d8224da58fdaee7daadb7
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index 2e3b4b2..d038ef3 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -1137,6 +1137,7 @@
 	struct vcpu *new_vcpu = NULL;
 	uintreg_t ec = GET_ESR_EC(esr);
 	bool is_el0_partition = vcpu->vm->el0_partition;
+	bool resume = false;
 
 	switch (ec) {
 	case EC_WFI_WFE:
@@ -1171,13 +1172,25 @@
 	case EC_DATA_ABORT_LOWER_EL:
 		info = fault_info_init(
 			esr, vcpu, (esr & (1U << 6)) ? MM_MODE_W : MM_MODE_R);
-		if (vcpu_handle_page_fault(vcpu, &info)) {
-			return NULL;
-		}
 
+		resume = vcpu_handle_page_fault(vcpu, &info);
 		if (is_el0_partition) {
 			dlog_warning("Data abort on EL0 partition\n");
-			return api_abort(vcpu);
+			/*
+			 * Abort EL0 context if we should not resume the
+			 * context, or it is an alignment fault.
+			 * vcpu_handle_page_fault() only checks the mode of the
+			 * page in an architecture agnostic way but alignment
+			 * faults on aarch64 can happen on a correctly mapped
+			 * page.
+			 */
+			if (!resume || ((esr & 0x3f) == 0x21)) {
+				return api_abort(vcpu);
+			}
+		}
+
+		if (resume) {
+			return NULL;
 		}
 
 		/* Inform the EL1 of the data abort. */
@@ -1188,6 +1201,7 @@
 
 	case EC_INSTRUCTION_ABORT_LOWER_EL:
 		info = fault_info_init(esr, vcpu, MM_MODE_X);
+
 		if (vcpu_handle_page_fault(vcpu, &info)) {
 			return NULL;
 		}