Page MenuHomeFreeBSD

D45528.id140226.diff
No OneTemporary

D45528.id140226.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
@@ -67,19 +67,6 @@
/* Enter the kernel exception level */
bl enter_kernel_el
- /*
- * Disable the MMU. We may have entered the kernel with it on and
- * will need to update the tables later. If this has been set up
- * with anything other than a VA == PA map then this will fail,
- * but in this case the code to find where we are running from
- * would have also failed.
- */
- dsb sy
- mrs x2, sctlr_el1
- bic x2, x2, SCTLR_M
- msr sctlr_el1, x2
- isb
-
/* Set the context id */
msr contextidr_el1, xzr
@@ -314,19 +301,37 @@
* registers and drop to EL1.
*/
LENTRY(enter_kernel_el)
+#define INIT_SCTLR_EL1 (SCTLR_LSMAOE | SCTLR_nTLSMD | SCTLR_EIS | \
+ SCTLR_TSCXT | SCTLR_EOS)
mrs x23, CurrentEL
and x23, x23, #(CURRENTEL_EL_MASK)
cmp x23, #(CURRENTEL_EL_EL2)
b.eq 1f
- ret
+
+ ldr x2, =INIT_SCTLR_EL1
+ msr sctlr_el1, x2
+ /* SCTLR_EOS is set so eret is a context synchronizing event so we
+ * need an isb here to ensure it's observed by later instructions,
+ * but don't need it in the eret below.
+ */
+ isb
+
+ /* Ensure SPSR_EL1 and pstate are in sync. The only wat to set the
+ * latter is to set the former and return from an exception with eret.
+ */
+ mov x2, #(PSR_DAIF | PSR_M_EL1h)
+ msr spsr_el1, x2
+ msr elr_el1, lr
+ eret
+
1:
+ dsb sy
/*
- * Disable the MMU. If the HCR_EL2.E2H field is set we will clear it
- * which may break address translation.
+ * Set just the reserved bits in sctlr_el2. This will disable the
+ * MMU which may have broken the kernel if we enter the kernel in
+ * EL2, e.g. when using VHE.
*/
- dsb sy
- mrs x2, sctlr_el2
- bic x2, x2, SCTLR_M
+ ldr x2, =(SCTLR_EL2_RES1 | SCTLR_EL2_EIS | SCTLR_EL2_EOS)
msr sctlr_el2, x2
isb
@@ -346,8 +351,8 @@
mrs x2, mpidr_el1
msr vmpidr_el2, x2
- /* Set the bits that need to be 1 in sctlr_el1 */
- ldr x2, .Lsctlr_res1
+ /* Set the initial sctlr_el1 */
+ ldr x2, =INIT_SCTLR_EL1
msr sctlr_el1, x2
/*
@@ -403,10 +408,7 @@
isb
eret
-
- .align 3
-.Lsctlr_res1:
- .quad SCTLR_RES1
+#undef INIT_SCTLR_EL1
LEND(enter_kernel_el)
/*
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
@@ -148,10 +148,14 @@
#define SCTLR_EL2_C (0x1UL << SCTLR_EL2_C_SHIFT)
#define SCTLR_EL2_SA_SHIFT 3
#define SCTLR_EL2_SA (0x1UL << SCTLR_EL2_SA_SHIFT)
+#define SCTLR_EL2_EOS_SHIFT 11
+#define SCTLR_EL2_EOS (0x1UL << SCTLR_EL2_EOS_SHIFT)
#define SCTLR_EL2_I_SHIFT 12
#define SCTLR_EL2_I (0x1UL << SCTLR_EL2_I_SHIFT)
#define SCTLR_EL2_WXN_SHIFT 19
#define SCTLR_EL2_WXN (0x1UL << SCTLR_EL2_WXN_SHIFT)
+#define SCTLR_EL2_EIS_SHIFT 22
+#define SCTLR_EL2_EIS (0x1UL << SCTLR_EL2_EIS_SHIFT)
#define SCTLR_EL2_EE_SHIFT 25
#define SCTLR_EL2_EE (0x1UL << SCTLR_EL2_EE_SHIFT)

File Metadata

Mime Type
text/plain
Expires
Sun, Oct 26, 4:08 PM (9 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24238096
Default Alt Text
D45528.id140226.diff (2 KB)

Event Timeline