ret                                     // to __primary_switch()
 0:
 #endif
+       bl      switch_to_vhe                   // Prefer VHE if possible
        add     sp, sp, #16
        mov     x29, #0
        mov     x30, #0
        eret
 
 SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
-#ifdef CONFIG_ARM64_VHE
-       /*
-        * Check for VHE being present. x2 being non-zero indicates that we
-        * do have VHE, and that the kernel is intended to run at EL2.
-        */
-       mrs     x2, id_aa64mmfr1_el1
-       ubfx    x2, x2, #ID_AA64MMFR1_VHE_SHIFT, #4
-#else
-       mov     x2, xzr
-#endif
-       cbz     x2, init_el2_nvhe
-
-       /*
-        * When VHE _is_ in use, EL1 will not be used in the host and
-        * requires no configuration, and all non-hyp-specific EL2 setup
-        * will be done via the _EL1 system register aliases in __cpu_setup.
-        */
-       mov_q   x0, HCR_HOST_VHE_FLAGS
-       msr     hcr_el2, x0
-       isb
-
-       init_el2_state vhe
-
-       isb
-
-       mov_q   x0, INIT_PSTATE_EL2
-       msr     spsr_el2, x0
-       msr     elr_el2, lr
-       mov     w0, #BOOT_CPU_MODE_EL2
-       eret
-
-SYM_INNER_LABEL(init_el2_nvhe, SYM_L_LOCAL)
-       /*
-        * When VHE is not in use, early init of EL2 and EL1 needs to be
-        * done here.
-        */
        mov_q   x0, INIT_SCTLR_EL1_MMU_OFF
        msr     sctlr_el1, x0
 
        /*
         * Common entry point for secondary CPUs.
         */
+       bl      switch_to_vhe
        bl      __cpu_secondary_check52bitva
        bl      __cpu_setup                     // initialise processor
        adrp    x1, swapper_pg_dir
 
        hvc     #0
        ret
 SYM_FUNC_END(__hyp_reset_vectors)
+
+/*
+ * Entry point to switch to VHE if deemed capable
+ */
+SYM_FUNC_START(switch_to_vhe)
+#ifdef CONFIG_ARM64_VHE
+       // Need to have booted at EL2
+       adr_l   x1, __boot_cpu_mode
+       ldr     w0, [x1]
+       cmp     w0, #BOOT_CPU_MODE_EL2
+       b.ne    1f
+
+       // and still be at EL1
+       mrs     x0, CurrentEL
+       cmp     x0, #CurrentEL_EL1
+       b.ne    1f
+
+       // Turn the world upside down
+       mov     x0, #HVC_VHE_RESTART
+       hvc     #0
+1:
+#endif
+       ret
+SYM_FUNC_END(switch_to_vhe)