|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] Force close the frontend if responses have been faked
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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |