From dc8616edc580806afb1efaec1cdc3cc9a1b3804e Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Fri, 24 Feb 2023 13:37:20 -0600 Subject: [PATCH] arm64: set FPEN if we're stuck with HCR_EL2.E2H On Apple Silicon systems, E2H can't actually be cleared; we're stuck with it. Check it again when we're setting up CPTR_EL2 and set FPEN appropriately to avoid later trapping to EL2 on writes to SIMD registers. Reviewed by: andrew Differential Revision: https://reviews.freebsd.org/D38819 --- sys/arm64/arm64/locore.S | 15 +++++++++++++-- sys/arm64/include/hypervisor.h | 4 ++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S index b37442f15f05..da3001711955 100644 --- a/sys/arm64/arm64/locore.S +++ b/sys/arm64/arm64/locore.S @@ -263,6 +263,10 @@ LENTRY(drop_to_el1) ldr x2, =(HCR_RW | HCR_APK | HCR_API) msr hcr_el2, x2 + /* Stash value of HCR_EL2 for later */ + isb + mrs x4, hcr_el2 + /* Load the Virtualization Process ID Register */ mrs x2, midr_el1 msr vpidr_el2, x2 @@ -275,8 +279,15 @@ LENTRY(drop_to_el1) ldr x2, .Lsctlr_res1 msr sctlr_el1, x2 - /* Don't trap to EL2 for exceptions */ - mov x2, #CPTR_RES1 + /* + * On some hardware, e.g., Apple M1, we can't clear E2H, so make sure we + * don't trap to EL2 for SIMD register usage to have at least a + * minimally usable system. + */ + tst x4, #HCR_E2H + mov x3, #CPTR_RES1 /* HCR_E2H == 0 */ + mov x4, #CPTR_FPEN /* HCR_E2H == 1 */ + csel x2, x3, x4, eq msr cptr_el2, x2 /* Don't trap to EL2 for CP15 traps */ diff --git a/sys/arm64/include/hypervisor.h b/sys/arm64/include/hypervisor.h index 84abe17f310e..0a0f0c2b3d07 100644 --- a/sys/arm64/include/hypervisor.h +++ b/sys/arm64/include/hypervisor.h @@ -45,9 +45,13 @@ #define CNTHCTL_EL1PCTEN (1 << 0) /*Allow EL0/1 physical counter access*/ /* CPTR_EL2 - Architecture feature trap register */ +/* Valid if HCR_EL2.E2H == 0 */ #define CPTR_RES0 0x7fefc800 #define CPTR_RES1 0x000033ff #define CPTR_TFP 0x00000400 +/* Valid if HCR_EL2.E2H == 1 */ +#define CPTR_FPEN 0x00300000 +/* Unconditionally valid */ #define CPTR_TTA 0x00100000 #define CPTR_TCPAC 0x80000000