The branch main has been updated by andrew:

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

commit a745cdc19b7f92b490f7c332abad82945f3b06cb
Author:     Andrew Turner <[email protected]>
AuthorDate: 2024-08-19 12:43:37 +0000
Commit:     Andrew Turner <[email protected]>
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;

Reply via email to