diff options
author | Kyle Evans <kevans@FreeBSD.org> | 2023-02-24 19:37:20 +0000 |
---|---|---|
committer | Kyle Evans <kevans@FreeBSD.org> | 2023-02-28 22:16:14 +0000 |
commit | dc8616edc580806afb1efaec1cdc3cc9a1b3804e (patch) | |
tree | fb7489c81065c11885978e3ad18695ead64ad790 | |
parent | 996606792ff9cfb2a115b6c6ee3d456afa5047f3 (diff) | |
download | src-dc8616edc580806afb1efaec1cdc3cc9a1b3804e.tar.gz src-dc8616edc580806afb1efaec1cdc3cc9a1b3804e.zip |
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
-rw-r--r-- | sys/arm64/arm64/locore.S | 15 | ||||
-rw-r--r-- | 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 |