diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S --- a/sys/arm64/arm64/locore.S +++ b/sys/arm64/arm64/locore.S @@ -263,6 +263,10 @@ 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 @@ 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 --- 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