Page MenuHomeFreeBSD

D46087.id141268.diff
No OneTemporary

D46087.id141268.diff

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
@@ -296,8 +296,12 @@
#endif
/*
- * If we are started in EL2, configure the required hypervisor
- * registers and drop to EL1.
+ * Enter the exception level the kernel will use:
+ *
+ * - If in EL1 continue in EL1
+ * - If the CPU supports FEAT_VHE then set HCR_E2H and HCR_TGE and continue
+ * in EL2
+ * - Configure EL2 to support running the kernel at EL1 and exit to that
*/
LENTRY(enter_kernel_el)
#define INIT_SCTLR_EL1 (SCTLR_LSMAOE | SCTLR_nTLSMD | SCTLR_EIS | \
@@ -335,13 +339,14 @@
isb
/* Configure the Hypervisor */
- ldr x2, =(HCR_RW | HCR_APK | HCR_API)
+ ldr x2, =(HCR_RW | HCR_APK | HCR_API | HCR_E2H)
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
@@ -354,41 +359,51 @@
ldr x2, =INIT_SCTLR_EL1
msr sctlr_el1, x2
+ /* Check if the E2H flag is set */
+ tst x4, #HCR_E2H
+ b.eq .Lno_vhe
+
/*
- * 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.
+ * The kernel will be running in EL2, route exceptions here rather
+ * than EL1.
*/
- tst x4, #HCR_E2H
- mov x3, #CPTR_RES1 /* HCR_E2H == 0 */
- mov x5, #CPTR_FPEN /* HCR_E2H == 1 */
- csel x2, x3, x5, eq
+ orr x4, x4, #(HCR_TGE)
+ msr hcr_el2, x4
+ isb
+
+ msr SCTLR_EL12_REG, x2
+ ldr x2, =(CPTR_FPEN)
+ ldr x3, =(CNTHCTL_E2H_EL1PCTEN | CNTHCTL_E2H_EL1PTEN)
+ ldr x5, =(PSR_DAIF | PSR_M_EL2h)
+ b .Ldone_vhe
+
+.Lno_vhe:
+ /* Hypervisor trap functions */
+ adrp x2, hyp_stub_vectors
+ add x2, x2, :lo12:hyp_stub_vectors
+ msr vbar_el2, x2
+
+ ldr x2, =(CPTR_RES1)
+ ldr x3, =(CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN)
+ ldr x5, =(PSR_DAIF | PSR_M_EL1h)
+
+.Ldone_vhe:
+
msr cptr_el2, x2
+ /* Enable access to the physical timers at EL1 */
+ msr cnthctl_el2, x3
+ /* Set the return PSTATE */
+ msr spsr_el2, x5
/* Don't trap to EL2 for CP15 traps */
msr hstr_el2, xzr
- /* Enable access to the physical timers at EL1 */
- tst x4, #HCR_E2H
- ldr x3, =(CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN)
- ldr x5, =(CNTHCTL_E2H_EL1PCTEN | CNTHCTL_E2H_EL1PTEN)
- csel x2, x3, x5, eq
- msr cnthctl_el2, x2
-
/* Set the counter offset to a known value */
msr cntvoff_el2, xzr
- /* Hypervisor trap functions */
- adrp x2, hyp_stub_vectors
- add x2, x2, :lo12:hyp_stub_vectors
- msr vbar_el2, x2
-
/* Zero vttbr_el2 so a hypervisor can tell the host and guest apart */
msr vttbr_el2, xzr
- mov x2, #(PSR_DAIF | PSR_M_EL1h)
- msr spsr_el2, x2
-
/* Configure GICv3 CPU interface */
mrs x2, id_aa64pfr0_el1
/* Extract GIC bits from the register */

File Metadata

Mime Type
text/plain
Expires
Thu, May 1, 12:58 PM (20 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17877335
Default Alt Text
D46087.id141268.diff (2 KB)

Event Timeline