git: a745cdc19b7f - main - arm64/vmm: Teach the vtimer about VHE
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 20 Aug 2024 09:02:16 UTC
The branch main has been updated by andrew:
URL: https://cgit.FreeBSD.org/src/commit/?id=a745cdc19b7f92b490f7c332abad82945f3b06cb
commit a745cdc19b7f92b490f7c332abad82945f3b06cb
Author: Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2024-08-19 12:43:37 +0000
Commit: Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2024-08-20 08:49:15 +0000
arm64/vmm: Teach the vtimer about VHE
Teach the virtual timer about the cnthctl_el2 field layout under VHE.
As with non-VHE we need to trap the physical timer and not trap the
virtual timer.
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D46074
---
sys/arm64/include/hypervisor.h | 4 ++++
sys/arm64/vmm/io/vtimer.c | 38 +++++++++++++++++++++++++++++++++-----
2 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/sys/arm64/include/hypervisor.h b/sys/arm64/include/hypervisor.h
index 011f86e83fdf..4c501e2722a9 100644
--- a/sys/arm64/include/hypervisor.h
+++ b/sys/arm64/include/hypervisor.h
@@ -41,6 +41,10 @@
#define CNTHCTL_EL1PCTEN (1 << 0) /* Allow physical counter access */
#define CNTHCTL_EL1PCEN (1 << 1) /* Allow physical timer access */
/* Valid if HCR_EL2.E2H == 1 */
+#define CNTHCTL_E2H_EL0PCTEN (1 << 0) /* Allow EL0 physical counter access */
+#define CNTHCTL_E2H_EL0VCTEN (1 << 1) /* Allow EL0 virtual counter access */
+#define CNTHCTL_E2H_EL0VTEN (1 << 8)
+#define CNTHCTL_E2H_EL0PTEN (1 << 9)
#define CNTHCTL_E2H_EL1PCTEN (1 << 10) /* Allow physical counter access */
#define CNTHCTL_E2H_EL1PTEN (1 << 11) /* Allow physical timer access */
/* Unconditionally valid */
diff --git a/sys/arm64/vmm/io/vtimer.c b/sys/arm64/vmm/io/vtimer.c
index aa0b3ff1588e..f59d7ebc1ad4 100644
--- a/sys/arm64/vmm/io/vtimer.c
+++ b/sys/arm64/vmm/io/vtimer.c
@@ -129,14 +129,42 @@ vtimer_vminit(struct hyp *hyp)
{
uint64_t now;
+ hyp->vtimer.cnthctl_el2 = cnthctl_el2_reg;
+
/*
* Configure the Counter-timer Hypervisor Control Register for the VM.
- *
- * CNTHCTL_EL1PCEN: trap access to CNTP_{CTL, CVAL, TVAL}_EL0 from EL1
- * CNTHCTL_EL1PCTEN: trap access to CNTPCT_EL0
*/
- hyp->vtimer.cnthctl_el2 = cnthctl_el2_reg & ~CNTHCTL_EL1PCEN;
- hyp->vtimer.cnthctl_el2 &= ~CNTHCTL_EL1PCTEN;
+ if (in_vhe()) {
+ /*
+ * CNTHCTL_E2H_EL0PCTEN: trap EL0 access to CNTP{CT,CTSS}_EL0
+ * CNTHCTL_E2H_EL1VCTEN: don't trap EL0 access to
+ * CNTV{CT,CTSS}_EL0
+ * CNTHCTL_E2H_EL0VTEN: don't trap EL0 access to
+ * CNTV_{CTL,CVAL,TVAL}_EL0
+ * CNTHCTL_E2H_EL0PTEN: trap EL0 access to
+ * CNTP_{CTL,CVAL,TVAL}_EL0
+ * CNTHCTL_E2H_EL1PCEN: trap EL1 access to
+ CNTP_{CTL,CVAL,TVAL}_EL0
+ * CNTHCTL_E2H_EL1PCTEN: trap access to CNTPCT_EL0
+ *
+ * TODO: Don't trap when FEAT_ECV is present
+ */
+ hyp->vtimer.cnthctl_el2 &= ~CNTHCTL_E2H_EL0PCTEN;
+ hyp->vtimer.cnthctl_el2 |= CNTHCTL_E2H_EL0VCTEN;
+ hyp->vtimer.cnthctl_el2 |= CNTHCTL_E2H_EL0VTEN;
+ hyp->vtimer.cnthctl_el2 &= ~CNTHCTL_E2H_EL0PTEN;
+
+ hyp->vtimer.cnthctl_el2 &= ~CNTHCTL_E2H_EL1PTEN;
+ hyp->vtimer.cnthctl_el2 &= ~CNTHCTL_E2H_EL1PCTEN;
+ } else {
+ /*
+ * CNTHCTL_EL1PCEN: trap access to CNTP_{CTL, CVAL, TVAL}_EL0
+ * from EL1
+ * CNTHCTL_EL1PCTEN: trap access to CNTPCT_EL0
+ */
+ hyp->vtimer.cnthctl_el2 &= ~CNTHCTL_EL1PCEN;
+ hyp->vtimer.cnthctl_el2 &= ~CNTHCTL_EL1PCTEN;
+ }
now = READ_SPECIALREG(cntpct_el0);
hyp->vtimer.cntvoff_el2 = now;