git: 02f3d094aead - main - Use the arm physical timer when able

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Wed, 15 Mar 2023 15:49:17 UTC
The branch main has been updated by andrew:

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

commit 02f3d094aead055d0ebc709c251c124e6f652fb6
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2023-03-15 13:33:02 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2023-03-15 15:49:00 +0000

    Use the arm physical timer when able
    
    To allow bhyve manage the virtual timer while in a guest have FreeBSD
    use the virtual timer only when bhyve will be unavailable due to not
    starting at EL2 where the hypervisor switcher will run.
    
    Reviewed by:    imp, kevans
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D39093
---
 sys/arm/arm/generic_timer.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index 36747441ec88..b36fbdf8dcbe 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -655,8 +655,13 @@ arm_tmr_attach(device_t dev)
 	}
 
 #ifdef __aarch64__
-	/* Use the virtual timer if we have one. */
-	if (sc->irqs[GT_VIRT].res != NULL) {
+	/*
+	 * Use the virtual timer when we can't use the hypervisor.
+	 * A hypervisor guest may change the virtual timer registers while
+	 * executing so any use of the virtual timer interrupt needs to be
+	 * coordinated with the virtual machine manager.
+	 */
+	if (!HAS_PHYS) {
 		sc->physical = false;
 		first_timer = GT_VIRT;
 		last_timer = GT_VIRT;
@@ -687,12 +692,9 @@ arm_tmr_attach(device_t dev)
 		}
 	}
 
-	/* Disable the virtual timer until we are ready */
-	if (sc->irqs[GT_VIRT].res != NULL)
-		arm_tmr_disable(false);
-	/* And the physical */
-	if ((sc->irqs[GT_PHYS_SECURE].res != NULL ||
-	    sc->irqs[GT_PHYS_NONSECURE].res != NULL) && HAS_PHYS)
+	/* Disable the timers until we are ready */
+	arm_tmr_disable(false);
+	if (HAS_PHYS)
 		arm_tmr_disable(true);
 
 	arm_tmr_timecount.tc_frequency = sc->clkfreq;