git: e6674c8f7fe7 - stable/13 - bhyve: allow reading of fwctl signature multiple times

From: Emmanuel Vadot <manu_at_FreeBSD.org>
Date: Mon, 17 Jan 2022 16:22:15 UTC
The branch stable/13 has been updated by manu:

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

commit e6674c8f7fe765aa72f99bff9bab381737bac896
Author:     Corvin Köhne <CorvinK@beckhoff.com>
AuthorDate: 2022-01-03 13:18:31 +0000
Commit:     Emmanuel Vadot <manu@FreeBSD.org>
CommitDate: 2022-01-17 12:53:17 +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
    
    (cherry picked from commit 8ec366ec6c943550a011effe50bc73e3875f8ead)
---
 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 0640bc28ba2b..abb234fe1de4 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;
 	}
 }