arm64/gcs: Provide basic EL2 setup to allow GCS usage at EL0 and EL1
authorMark Brown <broonie@kernel.org>
Tue, 1 Oct 2024 22:58:50 +0000 (23:58 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Fri, 4 Oct 2024 11:04:35 +0000 (12:04 +0100)
There is a control HCRX_EL2.GCSEn which must be set to allow GCS
features to take effect at lower ELs and also fine grained traps for GCS
usage at EL0 and EL1.  Configure all these to allow GCS usage by EL0 and
EL1.

We also initialise GCSCR_EL1 and GCSCRE0_EL1 to ensure that we can
execute function call instructions without faulting regardless of the
state when the kernel is started.

Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20241001-arm64-gcs-v13-11-222b78d87eee@kernel.org
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/include/asm/el2_setup.h

index e0ffdf13a18b3fe969b4ea6e4b49ff62a83053ce..27086a81eae34483a682681ab1be1959a339527a 100644 (file)
        ubfx    x0, x0, #ID_AA64MMFR1_EL1_HCX_SHIFT, #4
        cbz     x0, .Lskip_hcrx_\@
        mov_q   x0, HCRX_HOST_FLAGS
+
+        /* Enable GCS if supported */
+       mrs_s   x1, SYS_ID_AA64PFR1_EL1
+       ubfx    x1, x1, #ID_AA64PFR1_EL1_GCS_SHIFT, #4
+       cbz     x1, .Lset_hcrx_\@
+       orr     x0, x0, #HCRX_EL2_GCSEn
+
+.Lset_hcrx_\@:
        msr_s   SYS_HCRX_EL2, x0
 .Lskip_hcrx_\@:
 .endm
        orr     x0, x0, #HFGxTR_EL2_nPOR_EL0
 
 .Lskip_poe_fgt_\@:
+       /* GCS depends on PIE so we don't check it if PIE is absent */
+       mrs_s   x1, SYS_ID_AA64PFR1_EL1
+       ubfx    x1, x1, #ID_AA64PFR1_EL1_GCS_SHIFT, #4
+       cbz     x1, .Lset_fgt_\@
+
+       /* Disable traps of access to GCS registers at EL0 and EL1 */
+       orr     x0, x0, #HFGxTR_EL2_nGCS_EL1_MASK
+       orr     x0, x0, #HFGxTR_EL2_nGCS_EL0_MASK
+
+.Lset_fgt_\@:
        msr_s   SYS_HFGRTR_EL2, x0
        msr_s   SYS_HFGWTR_EL2, x0
        msr_s   SYS_HFGITR_EL2, xzr
 .Lskip_fgt_\@:
 .endm
 
+.macro __init_el2_gcs
+       mrs_s   x1, SYS_ID_AA64PFR1_EL1
+       ubfx    x1, x1, #ID_AA64PFR1_EL1_GCS_SHIFT, #4
+       cbz     x1, .Lskip_gcs_\@
+
+       /* Ensure GCS is not enabled when we start trying to do BLs */
+       msr_s   SYS_GCSCR_EL1, xzr
+       msr_s   SYS_GCSCRE0_EL1, xzr
+.Lskip_gcs_\@:
+.endm
+
 .macro __init_el2_nvhe_prepare_eret
        mov     x0, #INIT_PSTATE_EL1
        msr     spsr_el2, x0
        __init_el2_nvhe_idregs
        __init_el2_cptr
        __init_el2_fgt
+        __init_el2_gcs
 .endm
 
 #ifndef __KVM_NVHE_HYPERVISOR__