arm64: Disable fine grained traps on boot
authorMark Brown <broonie@kernel.org>
Thu, 1 Apr 2021 18:09:40 +0000 (19:09 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Thu, 8 Apr 2021 17:39:18 +0000 (18:39 +0100)
The arm64 FEAT_FGT extension introduces a set of traps to EL2 for accesses
to small sets of registers and instructions from EL1 and EL0.  Currently
Linux makes no use of this feature, ensure that it is not active at boot by
disabling the traps during EL2 setup.

Signed-off-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20210401180942.35815-3-broonie@kernel.org
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/include/asm/el2_setup.h
arch/arm64/include/asm/sysreg.h

index d77d358..b3f2d3b 100644 (file)
 .Lskip_sve_\@:
 .endm
 
+/* Disable any fine grained traps */
+.macro __init_el2_fgt
+       mrs     x1, id_aa64mmfr0_el1
+       ubfx    x1, x1, #ID_AA64MMFR0_FGT_SHIFT, #4
+       cbz     x1, .Lskip_fgt_\@
+
+       msr_s   SYS_HDFGRTR_EL2, xzr
+       msr_s   SYS_HDFGWTR_EL2, xzr
+       msr_s   SYS_HFGRTR_EL2, xzr
+       msr_s   SYS_HFGWTR_EL2, xzr
+       msr_s   SYS_HFGITR_EL2, xzr
+
+       mrs     x1, id_aa64pfr0_el1             // AMU traps UNDEF without AMU
+       ubfx    x1, x1, #ID_AA64PFR0_AMU_SHIFT, #4
+       cbz     x1, .Lskip_fgt_\@
+
+       msr_s   SYS_HAFGRTR_EL2, xzr
+.Lskip_fgt_\@:
+.endm
+
 .macro __init_el2_nvhe_prepare_eret
        mov     x0, #INIT_PSTATE_EL1
        msr     spsr_el2, x0
        __init_el2_nvhe_idregs
        __init_el2_nvhe_cptr
        __init_el2_nvhe_sve
+       __init_el2_fgt
        __init_el2_nvhe_prepare_eret
 .endm
 
index d4a5fca..b354689 100644 (file)
 #define SYS_PMCCFILTR_EL0              sys_reg(3, 3, 14, 15, 7)
 
 #define SYS_SCTLR_EL2                  sys_reg(3, 4, 1, 0, 0)
+#define SYS_HFGRTR_EL2                 sys_reg(3, 4, 1, 1, 4)
+#define SYS_HFGWTR_EL2                 sys_reg(3, 4, 1, 1, 5)
+#define SYS_HFGITR_EL2                 sys_reg(3, 4, 1, 1, 6)
 #define SYS_ZCR_EL2                    sys_reg(3, 4, 1, 2, 0)
 #define SYS_TRFCR_EL2                  sys_reg(3, 4, 1, 2, 1)
 #define SYS_DACR32_EL2                 sys_reg(3, 4, 3, 0, 0)
+#define SYS_HDFGRTR_EL2                        sys_reg(3, 4, 3, 1, 4)
+#define SYS_HDFGWTR_EL2                        sys_reg(3, 4, 3, 1, 5)
+#define SYS_HAFGRTR_EL2                        sys_reg(3, 4, 3, 1, 6)
 #define SYS_SPSR_EL2                   sys_reg(3, 4, 4, 0, 0)
 #define SYS_ELR_EL2                    sys_reg(3, 4, 4, 0, 1)
 #define SYS_IFSR32_EL2                 sys_reg(3, 4, 5, 0, 1)