git: 8c7ce2d48abf - main - bhyve: Defer virtio-console PORT_NAME until the guest is ready

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Wed, 30 Sep 2026 15:54:08 UTC
The branch main has been updated by markj:

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

commit 8c7ce2d48abfbf9fc08dccfb469fcc687c3cd68a
Author:     Hayzam Sherif <hayzam@gmail.com>
AuthorDate: 2026-09-30 14:16:38 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-09-30 15:53:51 +0000

    bhyve: Defer virtio-console PORT_NAME until the guest is ready
    
    pci_vtcon_announce_port() sends VIRTIO_CONSOLE_PORT_NAME immediately
    after VIRTIO_CONSOLE_DEVICE_ADD, without waiting for the guest to
    initialize the port.  The Windows virtio-serial driver ignores the
    name if the port is not yet available, which can prevent the QEMU
    guest agent from finding org.qemu.guest_agent.0.
    
    Send the name after the guest reports successful port initialization
    with VIRTIO_CONSOLE_PORT_READY, as QEMU does.
    
    While here, validate the guest-supplied port ID before forming a
    pointer into vsc_ports[].
    
    This ports the PORT_NAME ordering fix from illumos change 18082.
    
    Obtained from:  illumos 643ee887be44404b690eeaff14f20a27ad3c715c
    Reviewed by:    markj
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D59847
---
 usr.sbin/bhyve/pci_virtio_console.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/usr.sbin/bhyve/pci_virtio_console.c b/usr.sbin/bhyve/pci_virtio_console.c
index 2950c2276942..0efaba317d2f 100644
--- a/usr.sbin/bhyve/pci_virtio_console.c
+++ b/usr.sbin/bhyve/pci_virtio_console.c
@@ -515,13 +515,26 @@ pci_vtcon_control_tx(struct pci_vtcon_port *port, void *arg __unused,
 		break;
 
 	case VTCON_PORT_READY:
+		if (ctrl->id >= VTCON_MAXPORTS) {
+			WPRINTF(("VTCON_PORT_READY event for unknown port %d",
+			    ctrl->id));
+			return;
+		}
 		tmp = &sc->vsc_ports[ctrl->id];
-		if (ctrl->id >= VTCON_MAXPORTS || !tmp->vsp_enabled) {
+		if (!tmp->vsp_enabled) {
 			WPRINTF(("VTCON_PORT_READY event for unknown port %d",
 			    ctrl->id));
 			return;
 		}
 
+		if (ctrl->value == 1) {
+			resp.id = ctrl->id;
+			resp.event = VTCON_PORT_NAME;
+			resp.value = 1;
+			pci_vtcon_control_send(sc, &resp, tmp->vsp_name,
+			    strlen(tmp->vsp_name));
+		}
+
 		if (tmp->vsp_console) {
 			resp.event = VTCON_CONSOLE_PORT;
 			resp.id = ctrl->id;
@@ -541,10 +554,6 @@ pci_vtcon_announce_port(struct pci_vtcon_port *port)
 	event.event = VTCON_DEVICE_ADD;
 	event.value = 1;
 	pci_vtcon_control_send(port->vsp_sc, &event, NULL, 0);
-
-	event.event = VTCON_PORT_NAME;
-	pci_vtcon_control_send(port->vsp_sc, &event, port->vsp_name,
-	    strlen(port->vsp_name));
 }
 
 static void