Skip to content

Commit

Permalink
netkvm: fix BSOD if some queue fails to renew
Browse files Browse the repository at this point in the history
https://issues.redhat.com/browse/RHEL-68725
virtio-win#1197
In such case we do not have any other option than request to
unload the driver. This can happen in 2 flows: power up (during
fast startup) or reset, both with driver verifier that simulates
low resources.
In reset flow we need to request driver unload explicitly.
Power up flow works in SET_POWER, so it will do it automatically.

Signed-off-by: Yuri Benditovich <[email protected]>
  • Loading branch information
ybendito committed Dec 1, 2024
1 parent 359de33 commit 9c15277
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 7 deletions.
3 changes: 2 additions & 1 deletion NetKVM/Common/ParaNdis-AbstractPath.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ class CParaNdisAbstractPath
m_pVirtQueue->EnableInterrupts();
}

void Renew()
bool Renew()
{
m_pVirtQueue->Renew();
return m_pVirtQueue->IsValid();
}

ULONG getCPUIndex();
Expand Down
13 changes: 9 additions & 4 deletions NetKVM/Common/ParaNdis_Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2088,7 +2088,7 @@ ParaNdis_UpdateMAC(PARANDIS_ADAPTER *pContext)
NDIS_STATUS ParaNdis_PowerOn(PARANDIS_ADAPTER *pContext)
{
UINT i;

bool bRenewed = true;
DEBUG_ENTRY(0);
ParaNdis_DebugHistory(pContext, _etagHistoryLogOperation::hopPowerOn, NULL, 1, 0, 0);

Expand All @@ -2109,12 +2109,17 @@ NDIS_STATUS ParaNdis_PowerOn(PARANDIS_ADAPTER *pContext)

for (i = 0; i < pContext->nPathBundles; i++)
{
pContext->pPathBundles[i].txPath.Renew();
pContext->pPathBundles[i].rxPath.Renew();
bRenewed = bRenewed && pContext->pPathBundles[i].txPath.Renew();
bRenewed = bRenewed && pContext->pPathBundles[i].rxPath.Renew();
}
if (pContext->bCXPathCreated)
{
pContext->CXPath.Renew();
bRenewed = bRenewed && pContext->CXPath.Renew();
}

if (!bRenewed) {
DPrintf(0, "[%s] one or more queues failed to renew\n", __FUNCTION__);
return NDIS_STATUS_RESOURCES;
}

ParaNdis_RestoreDeviceConfigurationAfterReset(pContext);
Expand Down
11 changes: 9 additions & 2 deletions NetKVM/wlh/ParaNdis6_Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,12 +553,19 @@ static NDIS_STATUS ParaNdis6_Reset(
NDIS_HANDLE miniportAdapterContext,
PBOOLEAN pAddressingReset)
{
NDIS_STATUS status;
PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)miniportAdapterContext;
DEBUG_ENTRY(0);
ParaNdis_PowerOff(pContext);
ParaNdis_PowerOn(pContext);
status = ParaNdis_PowerOn(pContext);
*pAddressingReset = FALSE;
return NDIS_STATUS_SUCCESS;
// if ParaNdis_PowerOn fails, just returning error
// does not help, so request unload
if (!NT_SUCCESS(status)) {
DPrintf(0, "[%s] requesting removal\n", __FUNCTION__);
NdisMRemoveMiniport(pContext->MiniportHandle);
}
return status;
}

/***************************************************
Expand Down

0 comments on commit 9c15277

Please sign in to comment.