git: dc8616edc580 - main - arm64: set FPEN if we're stuck with HCR_EL2.E2H

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Tue, 28 Feb 2023 22:17:06 UTC
The branch main has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=dc8616edc580806afb1efaec1cdc3cc9a1b3804e

commit dc8616edc580806afb1efaec1cdc3cc9a1b3804e
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2023-02-24 19:37:20 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2023-02-28 22:16:14 +0000

    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