git: 8ec366ec6c94 - main - bhyve: allow reading of fwctl signature multiple times

From: Emmanuel Vadot <manu_at_FreeBSD.org>
Date: Mon, 03 Jan 2022 16:01:37 UTC
The branch main has been updated by manu:

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

commit 8ec366ec6c943550a011effe50bc73e3875f8ead
Author:     Corvin Köhne <CorvinK@beckhoff.com>
AuthorDate: 2022-01-03 13:18:31 +0000
Commit:     Emmanuel Vadot <manu@FreeBSD.org>
CommitDate: 2022-01-03 15:32:55 +0000

    bhyve: allow reading of fwctl signature multiple times
    
    At the moment, you only have one single chance to read the fwctl
    signature. At boot bhyve is in the state IDENT_WAIT. It's then
    possible to switch to IDENT_SEND. After bhyve sends the signature,
    it switches to REQ. From now on it's impossible to switch back to
    IDENT_SEND to read the signature. For that reason, only a single
    driver can read the signature. A guest can't use two drivers to
    identify that fwctl is present. It gets even worse when using
    OVMF. OVMF uses a library to access fwctl. Therefore, every single
    OVMF driver would try to read the signature. Currently, only a
    single OVMF driver accesses the fwctl. So, there's no issue with
    it yet. However, no OS driver would have a chance to detect fwctl when
    using OVMF because it's signature was already consumed by OVMF.
    
    Reviewed by:    markj
    MFC after:      2 weeks
    Sponsored by:   Beckhoff Automation GmbH & Co. KG
    Differential Revision:  https://reviews.freebsd.org/D31981
---
 usr.sbin/bhyve/fwctl.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/usr.sbin/bhyve/fwctl.c b/usr.sbin/bhyve/fwctl.c
index a91f3d14fb78..8faae30989e6 100644
--- a/usr.sbin/bhyve/fwctl.c
+++ b/usr.sbin/bhyve/fwctl.c
@@ -472,16 +472,18 @@ fwctl_inb(void)
 static void
 fwctl_outw(uint16_t val)
 {
-	switch (be_state) {
-	case IDENT_WAIT:
-		if (val == 0) {
-			be_state = IDENT_SEND;
-			ident_idx = 0;
-		}
-		break;
-	default:
-		/* ignore */
-		break;
+	if (be_state == DORMANT) {
+		return;
+	}
+
+	if (val == 0) {
+		/*
+		 * The guest wants to read the signature. It's possible that the
+		 * guest is unaware of the fwctl state at this moment. For that
+		 * reason, reset the state machine unconditionally.
+		 */
+		be_state = IDENT_SEND;
+		ident_idx = 0;
 	}
 }