#include <linux/compiler.h>
 #include <linux/kvm_host.h>
+#include <asm/alternative.h>
 #include <asm/sysreg.h>
 
 #define __hyp_text __section(.hyp.text) notrace
 {
        write_sysreg(kvm->arch.vtcr, vtcr_el2);
        write_sysreg(kvm->arch.vttbr, vttbr_el2);
+
+       /*
+        * ARM erratum 1165522 requires the actual execution of the above
+        * before we can switch to the EL1/EL0 translation regime used by
+        * the guest.
+        */
+       asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_1165522));
 }
 
 #endif /* __ARM64_KVM_HYP_H__ */
 
 {
        extern char vectors[];  /* kernel exception vectors */
        write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
+
+       /*
+        * ARM erratum 1165522 requires the actual execution of the above
+        * before we can switch to the EL2/EL0 translation regime used by
+        * the host.
+        */
+       asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_1165522));
+
        write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1);
        write_sysreg(vectors, vbar_el1);
 }
 
        sysreg_save_host_state_vhe(host_ctxt);
 
+       /*
+        * ARM erratum 1165522 requires us to configure both stage 1 and
+        * stage 2 translation for the guest context before we clear
+        * HCR_EL2.TGE.
+        *
+        * We have already configured the guest's stage 1 translation in
+        * kvm_vcpu_load_sysregs above.  We must now call __activate_vm
+        * before __activate_traps, because __activate_vm configures
+        * stage 2 translation, and __activate_traps clear HCR_EL2.TGE
+        * (among other things).
+        */
        __activate_vm(vcpu->kvm);
        __activate_traps(vcpu);