Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[sfrench/cifs-2.6.git] / arch / arm64 / kernel / head.S
index f2eb206920a2ecf7b3fdbebf30c5096b398bbc64..42b23ce679dc78979ab397eda123d8dd3bd7de69 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <linux/linkage.h>
 #include <linux/init.h>
-#include <linux/irqchip/arm-gic-v3.h>
 #include <linux/pgtable.h>
 
 #include <asm/asm_pointer_auth.h>
@@ -21,6 +20,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/cache.h>
 #include <asm/cputype.h>
+#include <asm/el2_setup.h>
 #include <asm/elf.h>
 #include <asm/image.h>
 #include <asm/kernel-pgtable.h>
@@ -493,155 +493,56 @@ SYM_INNER_LABEL(init_el1, SYM_L_LOCAL)
        eret
 
 SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
-       mov_q   x0, INIT_SCTLR_EL2_MMU_OFF
-       msr     sctlr_el2, x0
-
 #ifdef CONFIG_ARM64_VHE
        /*
-        * Check for VHE being present. For the rest of the EL2 setup,
-        * x2 being non-zero indicates that we do have VHE, and that the
-        * kernel is intended to run at EL2.
+        * 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
 
-       /* Hyp configuration. */
-       mov_q   x0, HCR_HOST_NVHE_FLAGS
-       cbz     x2, set_hcr
+       /*
+        * 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
-set_hcr:
        msr     hcr_el2, x0
        isb
 
-       /*
-        * Allow Non-secure EL1 and EL0 to access physical timer and counter.
-        * This is not necessary for VHE, since the host kernel runs in EL2,
-        * and EL0 accesses are configured in the later stage of boot process.
-        * Note that when HCR_EL2.E2H == 1, CNTHCTL_EL2 has the same bit layout
-        * as CNTKCTL_EL1, and CNTKCTL_EL1 accessing instructions are redefined
-        * to access CNTHCTL_EL2. This allows the kernel designed to run at EL1
-        * to transparently mess with the EL0 bits via CNTKCTL_EL1 access in
-        * EL2.
-        */
-       cbnz    x2, 1f
-       mrs     x0, cnthctl_el2
-       orr     x0, x0, #3                      // Enable EL1 physical timers
-       msr     cnthctl_el2, x0
-1:
-       msr     cntvoff_el2, xzr                // Clear virtual offset
-
-#ifdef CONFIG_ARM_GIC_V3
-       /* GICv3 system register access */
-       mrs     x0, id_aa64pfr0_el1
-       ubfx    x0, x0, #ID_AA64PFR0_GIC_SHIFT, #4
-       cbz     x0, 3f
-
-       mrs_s   x0, SYS_ICC_SRE_EL2
-       orr     x0, x0, #ICC_SRE_EL2_SRE        // Set ICC_SRE_EL2.SRE==1
-       orr     x0, x0, #ICC_SRE_EL2_ENABLE     // Set ICC_SRE_EL2.Enable==1
-       msr_s   SYS_ICC_SRE_EL2, x0
-       isb                                     // Make sure SRE is now set
-       mrs_s   x0, SYS_ICC_SRE_EL2             // Read SRE back,
-       tbz     x0, #0, 3f                      // and check that it sticks
-       msr_s   SYS_ICH_HCR_EL2, xzr            // Reset ICC_HCR_EL2 to defaults
-
-3:
-#endif
-
-       /* Populate ID registers. */
-       mrs     x0, midr_el1
-       mrs     x1, mpidr_el1
-       msr     vpidr_el2, x0
-       msr     vmpidr_el2, x1
-
-#ifdef CONFIG_COMPAT
-       msr     hstr_el2, xzr                   // Disable CP15 traps to EL2
-#endif
-
-       /* EL2 debug */
-       mrs     x1, id_aa64dfr0_el1
-       sbfx    x0, x1, #ID_AA64DFR0_PMUVER_SHIFT, #4
-       cmp     x0, #1
-       b.lt    4f                              // Skip if no PMU present
-       mrs     x0, pmcr_el0                    // Disable debug access traps
-       ubfx    x0, x0, #11, #5                 // to EL2 and allow access to
-4:
-       csel    x3, xzr, x0, lt                 // all PMU counters from EL1
-
-       /* Statistical profiling */
-       ubfx    x0, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4
-       cbz     x0, 7f                          // Skip if SPE not present
-       cbnz    x2, 6f                          // VHE?
-       mrs_s   x4, SYS_PMBIDR_EL1              // If SPE available at EL2,
-       and     x4, x4, #(1 << SYS_PMBIDR_EL1_P_SHIFT)
-       cbnz    x4, 5f                          // then permit sampling of physical
-       mov     x4, #(1 << SYS_PMSCR_EL2_PCT_SHIFT | \
-                     1 << SYS_PMSCR_EL2_PA_SHIFT)
-       msr_s   SYS_PMSCR_EL2, x4               // addresses and physical counter
-5:
-       mov     x1, #(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT)
-       orr     x3, x3, x1                      // If we don't have VHE, then
-       b       7f                              // use EL1&0 translation.
-6:                                             // For VHE, use EL2 translation
-       orr     x3, x3, #MDCR_EL2_TPMS          // and disable access from EL1
-7:
-       msr     mdcr_el2, x3                    // Configure debug traps
-
-       /* LORegions */
-       mrs     x1, id_aa64mmfr1_el1
-       ubfx    x0, x1, #ID_AA64MMFR1_LOR_SHIFT, 4
-       cbz     x0, 1f
-       msr_s   SYS_LORC_EL1, xzr
-1:
-
-       /* Stage-2 translation */
-       msr     vttbr_el2, xzr
-
-       cbz     x2, install_el2_stub
+       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(install_el2_stub, SYM_L_LOCAL)
+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.
-        * 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, INIT_SCTLR_EL1_MMU_OFF
        msr     sctlr_el1, x0
 
-       /* Coprocessor traps. */
-       mov     x0, #0x33ff
-       msr     cptr_el2, x0                    // Disable copro. traps to EL2
-
-       /* SVE register access */
-       mrs     x1, id_aa64pfr0_el1
-       ubfx    x1, x1, #ID_AA64PFR0_SVE_SHIFT, #4
-       cbz     x1, 7f
-
-       bic     x0, x0, #CPTR_EL2_TZ            // Also disable SVE traps
-       msr     cptr_el2, x0                    // Disable copro. traps to EL2
+       mov_q   x0, HCR_HOST_NVHE_FLAGS
+       msr     hcr_el2, x0
        isb
-       mov     x1, #ZCR_ELx_LEN_MASK           // SVE: Enable full vector
-       msr_s   SYS_ZCR_EL2, x1                 // length for EL1.
+
+       init_el2_state nvhe
 
        /* Hypervisor stub */
-7:     adr_l   x0, __hyp_stub_vectors
+       adr_l   x0, __hyp_stub_vectors
        msr     vbar_el2, x0
-
        isb
-       mov     x0, #INIT_PSTATE_EL1
-       msr     spsr_el2, x0
+
        msr     elr_el2, lr
        mov     w0, #BOOT_CPU_MODE_EL2
        eret