feat: disable alignment check for EL0 partitions

Relax hw alignment check specifically for (S-)EL0 partitions when
Hafnium runs with VHE enabled. EL1 partitions have a specific control
for EL1 and EL0 with respect to alignment check.
Create a hyp_state structure (from already defined flying registers)
within the vCPU context to hold the Hypervisor EL2 static configuration
applied when a vCPU runs. This state is switched back and forth when
running the Hypervisor or the VM.
Add SCTLR_EL2 to this context. An EL0 partition context is initialized
with SCTLR_EL2.A=0 such that alignment check is disabled when EL0 runs
in the EL2&0 translation regime. SCTLR_EL2.A is set back when returning
to the Hypervisor such that Hypervisor execution runs with aligment
check enabled at EL2.
Remove HCR_EL2 saving from vCPU exit path provided this register state
is static and doesn't change while a vCPU runs.
The rationale for such change is to permit running upstream SW stacks
such as the EDKII/StandaloneMm [1] for which default build assumes
unaligned accesses are permitted. Similar query exists for running
Trusted Services on top of Hafnium [2].

[1] https://github.com/tianocore/edk2/tree/master/StandaloneMmPkg
[2] https://trusted-services.readthedocs.io/en/integration/

Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Change-Id: I2906f4c712425fcfb31adbf89e2e3b9ca293f181
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index 68a1777..fb7e549 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -271,9 +271,9 @@
 static void set_virtual_irq(struct arch_regs *r, bool enable)
 {
 	if (enable) {
-		r->hcr_el2 |= HCR_EL2_VI;
+		r->hyp_state.hcr_el2 |= HCR_EL2_VI;
 	} else {
-		r->hcr_el2 &= ~HCR_EL2_VI;
+		r->hyp_state.hcr_el2 &= ~HCR_EL2_VI;
 	}
 }
 
@@ -282,14 +282,15 @@
  */
 static void set_virtual_irq_current(bool enable)
 {
-	uintreg_t hcr_el2 = current()->regs.hcr_el2;
+	struct vcpu *vcpu = current();
+	uintreg_t hcr_el2 = vcpu->regs.hyp_state.hcr_el2;
 
 	if (enable) {
 		hcr_el2 |= HCR_EL2_VI;
 	} else {
 		hcr_el2 &= ~HCR_EL2_VI;
 	}
-	current()->regs.hcr_el2 = hcr_el2;
+	vcpu->regs.hyp_state.hcr_el2 = hcr_el2;
 }
 
 /**
@@ -299,9 +300,9 @@
 static void set_virtual_fiq(struct arch_regs *r, bool enable)
 {
 	if (enable) {
-		r->hcr_el2 |= HCR_EL2_VF;
+		r->hyp_state.hcr_el2 |= HCR_EL2_VF;
 	} else {
-		r->hcr_el2 &= ~HCR_EL2_VF;
+		r->hyp_state.hcr_el2 &= ~HCR_EL2_VF;
 	}
 }
 
@@ -310,14 +311,15 @@
  */
 static void set_virtual_fiq_current(bool enable)
 {
-	uintreg_t hcr_el2 = current()->regs.hcr_el2;
+	struct vcpu *vcpu = current();
+	uintreg_t hcr_el2 = vcpu->regs.hyp_state.hcr_el2;
 
 	if (enable) {
 		hcr_el2 |= HCR_EL2_VF;
 	} else {
 		hcr_el2 &= ~HCR_EL2_VF;
 	}
-	current()->regs.hcr_el2 = hcr_el2;
+	vcpu->regs.hyp_state.hcr_el2 = hcr_el2;
 }
 
 #if SECURE_WORLD == 1