git: 4dfa329f4861 - main - bhyve: Extend mevent to support updating timers

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Wed, 10 Apr 2024 15:19:26 UTC
The branch main has been updated by markj:

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

commit 4dfa329f48618d30e0c32529f874c1d0cc7beb00
Author:     Jessica Clarke <jrtc27@jrtc27.com>
AuthorDate: 2024-02-21 22:42:19 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-04-10 15:17:56 +0000

    bhyve: Extend mevent to support updating timers
    
    This will be used by a new PL031 implementation to provide an RTC for
    arm64 guests.
    
    Reviewed by:    jhb
    MFC after:      2 weeks
    Obtained from:  CheriBSD
---
 usr.sbin/bhyve/mevent.c | 34 ++++++++++++++++++++++++----------
 usr.sbin/bhyve/mevent.h |  1 +
 2 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/usr.sbin/bhyve/mevent.c b/usr.sbin/bhyve/mevent.c
index ce272ce87f3d..dbcc39148ca1 100644
--- a/usr.sbin/bhyve/mevent.c
+++ b/usr.sbin/bhyve/mevent.c
@@ -80,6 +80,12 @@ struct mevent {
 	LIST_ENTRY(mevent) me_list;
 };
 
+enum mevent_update_type {
+	UPDATE_ENABLE,
+	UPDATE_DISABLE,
+	UPDATE_TIMER,
+};
+
 static LIST_HEAD(listhead, mevent) global_head, change_head;
 
 static void
@@ -237,7 +243,6 @@ mevent_build(struct kevent *kev)
 			 */
 			close(mevp->me_fd);
 		} else {
-			assert((mevp->me_state & EV_ADD) == 0);
 			mevent_populate(mevp, &kev[i]);
 			i++;
 		}
@@ -375,30 +380,35 @@ mevent_add_disabled(int tfd, enum ev_type type,
 }
 
 static int
-mevent_update(struct mevent *evp, bool enable)
+mevent_update(struct mevent *evp, enum mevent_update_type type, int msecs)
 {
 	int newstate;
 
 	mevent_qlock();
 
 	/*
-	 * It's not possible to enable/disable a deleted event
+	 * It's not possible to update a deleted event
 	 */
 	assert((evp->me_state & EV_DELETE) == 0);
 
 	newstate = evp->me_state;
-	if (enable) {
+	if (type == UPDATE_ENABLE) {
 		newstate |= EV_ENABLE;
 		newstate &= ~EV_DISABLE;
-	} else {
+	} else if (type == UPDATE_DISABLE) {
 		newstate |= EV_DISABLE;
 		newstate &= ~EV_ENABLE;
+	} else {
+		assert(type == UPDATE_TIMER);
+		assert(evp->me_type == EVF_TIMER);
+		newstate |= EV_ADD;
+		evp->me_msecs = msecs;
 	}
 
 	/*
-	 * No update needed if state isn't changing
+	 * No update needed if enable/disable had no effect
 	 */
-	if (evp->me_state != newstate) {
+	if (evp->me_state != newstate || type == UPDATE_TIMER) {
 		evp->me_state = newstate;
 
 		/*
@@ -421,15 +431,19 @@ mevent_update(struct mevent *evp, bool enable)
 int
 mevent_enable(struct mevent *evp)
 {
-
-	return (mevent_update(evp, true));
+	return (mevent_update(evp, UPDATE_ENABLE, -1));
 }
 
 int
 mevent_disable(struct mevent *evp)
 {
+	return (mevent_update(evp, UPDATE_DISABLE, -1));
+}
 
-	return (mevent_update(evp, false));
+int
+mevent_timer_update(struct mevent *evp, int msecs)
+{
+	return (mevent_update(evp, UPDATE_TIMER, msecs));
 }
 
 static int
diff --git a/usr.sbin/bhyve/mevent.h b/usr.sbin/bhyve/mevent.h
index de70361059bd..23107fc55982 100644
--- a/usr.sbin/bhyve/mevent.h
+++ b/usr.sbin/bhyve/mevent.h
@@ -55,6 +55,7 @@ int	mevent_enable(struct mevent *evp);
 int	mevent_disable(struct mevent *evp);
 int	mevent_delete(struct mevent *evp);
 int	mevent_delete_close(struct mevent *evp);
+int	mevent_timer_update(struct mevent *evp, int msecs);
 
 void	mevent_dispatch(void);