aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2023-02-24 19:37:20 +0000
committerKyle Evans <kevans@FreeBSD.org>2023-02-28 22:16:14 +0000
commitdc8616edc580806afb1efaec1cdc3cc9a1b3804e (patch)
treefb7489c81065c11885978e3ad18695ead64ad790
parent996606792ff9cfb2a115b6c6ee3d456afa5047f3 (diff)
downloadsrc-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.S15
-rw-r--r--sys/arm64/include/hypervisor.h4
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