[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Force close the frontend if responses have been faked


  • To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
  • Date: Wed, 26 Aug 2026 11:23:36 +0200
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID"
  • Cc: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
  • Delivery-date: Wed, 26 Aug 2026 09:23:47 +0000
  • Feedback-id: default:8631fc262581453bbf619ec5b2062170:Sweego
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

If the ring disable process ended up faking responses, the shared ring
is no longer reusable and must be disconnected first. Otherwise, if the
ring is reenabled, the backend and frontend will desync.

Add a Poisoned flag to rings to indicate that they have been made
unusable. Introduce a transient Poisoned state to the frontend state
machine. If any ring has been poisoned, close the frontend before
reenabling it.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
---
 src/xenvif/frontend.c    | 34 +++++++++++++++++++++++++++++++++-
 src/xenvif/frontend.h    |  1 +
 src/xenvif/transmitter.c | 24 ++++++++++++++++++++++++
 src/xenvif/transmitter.h |  5 +++++
 4 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/src/xenvif/frontend.c b/src/xenvif/frontend.c
index 086d0df..b772349 100644
--- a/src/xenvif/frontend.c
+++ b/src/xenvif/frontend.c
@@ -129,6 +129,7 @@ FrontendStateName(
     _STATE_NAME(CLOSED);
     _STATE_NAME(PREPARED);
     _STATE_NAME(CONNECTED);
+    _STATE_NAME(POISONED);
     _STATE_NAME(ENABLED);
     default:
         break;
@@ -2687,6 +2688,15 @@ FrontendDisable(
     Trace("<====\n");
 }
 
+_IRQL_requires_(DISPATCH_LEVEL)
+static FORCEINLINE BOOLEAN
+FrontendIsPoisoned(
+    IN  PXENVIF_FRONTEND    Frontend
+    )
+{
+    return TransmitterIsPoisoned(__FrontendGetTransmitter(Frontend));
+}
+
 _IRQL_requires_max_(DISPATCH_LEVEL)
 NTSTATUS
 FrontendSetState(
@@ -2809,6 +2819,24 @@ FrontendSetState(
             }
             break;
 
+        case FRONTEND_POISONED:
+            switch (State) {
+            case FRONTEND_CONNECTED:
+            case FRONTEND_PREPARED:
+            case FRONTEND_CLOSED:
+            case FRONTEND_UNKNOWN:
+                FrontendClose(Frontend);
+                Frontend->State = FRONTEND_CLOSED;
+
+                FrontendDisconnect(Frontend);
+                break;
+
+            default:
+                ASSERT(FALSE);
+                break;
+            }
+            break;
+
         case FRONTEND_ENABLED:
             switch (State) {
             case FRONTEND_CONNECTED:
@@ -2816,7 +2844,11 @@ FrontendSetState(
             case FRONTEND_CLOSED:
             case FRONTEND_UNKNOWN:
                 FrontendDisable(Frontend);
-                Frontend->State = FRONTEND_CONNECTED;
+                if (FrontendIsPoisoned(Frontend)) {
+                    Frontend->State = FRONTEND_POISONED;
+                } else {
+                    Frontend->State = FRONTEND_CONNECTED;
+                }
                 break;
 
             default:
diff --git a/src/xenvif/frontend.h b/src/xenvif/frontend.h
index e062ed0..c1b7334 100644
--- a/src/xenvif/frontend.h
+++ b/src/xenvif/frontend.h
@@ -53,6 +53,7 @@ typedef enum _XENVIF_FRONTEND_STATE {
     FRONTEND_CLOSED,
     FRONTEND_PREPARED,
     FRONTEND_CONNECTED,
+    FRONTEND_POISONED,
     FRONTEND_ENABLED
 } XENVIF_FRONTEND_STATE, *PXENVIF_FRONTEND_STATE;
 
diff --git a/src/xenvif/transmitter.c b/src/xenvif/transmitter.c
index b78a090..8c4ee41 100644
--- a/src/xenvif/transmitter.c
+++ b/src/xenvif/transmitter.c
@@ -187,6 +187,7 @@ typedef struct _XENVIF_TRANSMITTER_RING {
     BOOLEAN                         Connected;
     BOOLEAN                         Enabled;
     BOOLEAN                         Stopped;
+    BOOLEAN                         Poisoned;
     PVOID                           Lock;
 #if DBG
     PKTHREAD                        LockThread;
@@ -2440,6 +2441,8 @@ __TransmitterRingFakeResponses(
         PXENVIF_TRANSMITTER Transmitter;
         PXENVIF_FRONTEND    Frontend;
 
+        Ring->Poisoned = TRUE;
+
         Transmitter = Ring->Transmitter;
         Frontend = Transmitter->Frontend;
 
@@ -3920,6 +3923,7 @@ __TransmitterRingEnable(
 
     __TransmitterRingAcquireLock(Ring);
 
+    BUG_ON(Ring->Poisoned);
     ASSERT(!Ring->Enabled);
     Ring->Enabled = TRUE;
 
@@ -4076,6 +4080,7 @@ __TransmitterRingDisconnect(
     Ring->ResponsesProcessed = 0;
     Ring->RequestsPushed = 0;
     Ring->RequestsPosted = 0;
+    Ring->Poisoned = FALSE;
 
     XENBUS_DEBUG(Deregister,
                  &Transmitter->DebugInterface,
@@ -4980,6 +4985,25 @@ TransmitterDisconnect(
     Trace("<====\n");
 }
 
+BOOLEAN
+TransmitterIsPoisoned(
+    IN  PXENVIF_TRANSMITTER Transmitter
+    )
+{
+    ULONG                   NumQueues;
+    ULONG                   Index;
+
+    NumQueues = FrontendGetNumQueues(Transmitter->Frontend);
+    for (Index = 0; Index < NumQueues; Index++) {
+        PXENVIF_TRANSMITTER_RING    Ring = Transmitter->Ring[Index];
+
+        if (Ring->Poisoned)
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
 _IRQL_requires_(PASSIVE_LEVEL)
 VOID
 TransmitterTeardown(
diff --git a/src/xenvif/transmitter.h b/src/xenvif/transmitter.h
index 5e789f1..5e8defc 100644
--- a/src/xenvif/transmitter.h
+++ b/src/xenvif/transmitter.h
@@ -81,6 +81,11 @@ TransmitterDisconnect(
     IN  PXENVIF_TRANSMITTER Transmitter
     );
 
+extern BOOLEAN
+TransmitterIsPoisoned(
+    IN  PXENVIF_TRANSMITTER Transmitter
+    );
+
 _IRQL_requires_(PASSIVE_LEVEL)
 extern VOID
 TransmitterTeardown(
-- 
2.55.0.windows.3



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.