[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:27 +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:36 +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/xenvbd/frontend.c | 30 +++++++++++++++++++++++++++++-
 src/xenvbd/frontend.h |  3 ++-
 src/xenvbd/ring.c     | 25 +++++++++++++++++++++++++
 src/xenvbd/ring.h     |  5 +++++
 4 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c
index d8e3287..3b078da 100644
--- a/src/xenvbd/frontend.c
+++ b/src/xenvbd/frontend.c
@@ -108,6 +108,7 @@ __XenvbdStateName(
     case XENVBD_CLOSED:             return "CLOSED";
     case XENVBD_PREPARED:           return "PREPARED";
     case XENVBD_CONNECTED:          return "CONNECTED";
+    case XENVBD_POISONED:           return "POISONED";
     case XENVBD_ENABLED:            return "ENABLED";
     default:                        return "UNKNOWN";
     }
@@ -1349,6 +1350,14 @@ FrontendDisable(
     RingDisable(Frontend->Ring);
     GranterDisable(Frontend->Granter);
 }
+__drv_requiresIRQL(DISPATCH_LEVEL)
+static FORCEINLINE BOOLEAN
+FrontendIsPoisoned(
+    __in  PXENVBD_FRONTEND          Frontend
+    )
+{
+    return RingIsPoisoned(Frontend->Ring);
+}
 
 //=============================================================================
 // Init/Term
@@ -1488,6 +1497,21 @@ __FrontendSetState(
             }
             break;
 
+        case XENVBD_POISONED:
+            switch (State) {
+            case XENVBD_CLOSING:
+            case XENVBD_CLOSED:
+            case XENVBD_PREPARED:
+            case XENVBD_CONNECTED:
+                Status = FrontendClose(Frontend);
+                Frontend->State = XENVBD_CLOSING;
+                break;
+            default:
+                Failed = TRUE;
+                break;
+            }
+            break;
+
         case XENVBD_ENABLED:
             switch (State) {
             case XENVBD_CLOSING:
@@ -1495,7 +1519,11 @@ __FrontendSetState(
             case XENVBD_PREPARED:
             case XENVBD_CONNECTED:
                 FrontendDisable(Frontend);
-                Frontend->State = XENVBD_CONNECTED;
+                if (FrontendIsPoisoned(Frontend)) {
+                    Frontend->State = XENVBD_POISONED;
+                } else {
+                    Frontend->State = XENVBD_CONNECTED;
+                }
                 break;
             default:
                 Failed = TRUE;
diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h
index 6c7665d..18cc4fb 100644
--- a/src/xenvbd/frontend.h
+++ b/src/xenvbd/frontend.h
@@ -47,7 +47,8 @@ typedef enum _XENVBD_STATE {
     XENVBD_CLOSED,      // -> { PREPARED }
     XENVBD_PREPARED,    // -> { CLOSING, CONNECTED }
     XENVBD_CONNECTED,   // -> { ENABLED, CLOSING }
-    XENVBD_ENABLED      // -> { CLOSING }
+    XENVBD_POISONED,    // -> { CLOSING }
+    XENVBD_ENABLED      // -> { CONNECTED, POISONED }
 } XENVBD_STATE, *PXENVBD_STATE;
 
 typedef struct _XENVBD_CAPS {
diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
index d7daaab..0b56831 100644
--- a/src/xenvbd/ring.c
+++ b/src/xenvbd/ring.c
@@ -75,6 +75,7 @@ typedef struct _XENVBD_BLKIF_RING {
     BOOLEAN                         Connected;
     BOOLEAN                         Enabled;
     BOOLEAN                         Stopped;
+    BOOLEAN                         Poisoned;
     PVOID                           Lock;
 #if DBG
     PKTHREAD                        LockThread;
@@ -2172,6 +2173,7 @@ BlkifRingEnable(
     Trace("====> %u\n", BlkifRing->Index);
 
     __BlkifRingAcquireLock(BlkifRing);
+    BUG_ON(BlkifRing->Poisoned);
     ASSERT(!BlkifRing->Enabled);
     BlkifRing->Enabled = TRUE;
     __BlkifRingReleaseLock(BlkifRing);
@@ -2249,6 +2251,8 @@ BlkifRingDisable(
         Request = CONTAINING_RECORD(ListEntry, XENVBD_REQUEST, ListEntry);
         BlkifRing->ResponsesProcessed++;
         __BlkifRingCompleteResponse(BlkifRing, Request, BLKIF_RSP_ERROR);
+
+        BlkifRing->Poisoned = TRUE;
     }
 
     while (!IsListEmpty(&BlkifRing->PreparedQueue)) {
@@ -2315,6 +2319,7 @@ BlkifRingDisconnect(
     BlkifRing->ResponsesProcessed = 0;
 
     BlkifRing->Connected = FALSE;
+    BlkifRing->Poisoned = FALSE;
 
     Trace("<==== %u\n", BlkifRing->Index);
 }
@@ -2770,6 +2775,26 @@ RingDisconnect(
     XENBUS_DEBUG(Release, &Ring->DebugInterface);
 }
 
+BOOLEAN
+RingIsPoisoned(
+    IN  PXENVBD_RING    Ring
+    )
+{
+    ULONG               NumQueues;
+    ULONG               Index;
+
+    NumQueues = FrontendGetNumQueues(Ring->Frontend);
+    for (Index = 0; Index < NumQueues; Index++) {
+        PXENVBD_BLKIF_RING  BlkifRing = Ring->Ring[Index];
+
+        if (BlkifRing->Poisoned) {
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
 static FORCEINLINE PXENVBD_BLKIF_RING
 __RingGetBlkifRing(
     IN  PXENVBD_RING    Ring,
diff --git a/src/xenvbd/ring.h b/src/xenvbd/ring.h
index c459838..5644c7c 100644
--- a/src/xenvbd/ring.h
+++ b/src/xenvbd/ring.h
@@ -75,6 +75,11 @@ RingDisconnect(
     IN  PXENVBD_RING    Ring
     );
 
+extern BOOLEAN
+RingIsPoisoned(
+    IN  PXENVBD_RING    Ring
+    );
+
 extern BOOLEAN
 RingQueueRequest(
     IN  PXENVBD_RING    Ring,
-- 
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®.