Skip to content

Commit

Permalink
Merge pull request #153 from lstipakov/fix_armb4_bsod
Browse files Browse the repository at this point in the history
Fix arm64 bsod
  • Loading branch information
lstipakov authored Apr 25, 2023
2 parents a78bab0 + b496fe1 commit b2aeda5
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 12 deletions.
75 changes: 75 additions & 0 deletions src/adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ tapAdapterContextAllocate(
// NBL pool for making TAP receive indications.
NdisZeroMemory(&nblPoolParameters, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));

// Initialize event used to determine when all receive NBLs have been returned.
NdisInitializeEvent(&adapter->ReceiveNblInFlightCountZeroEvent);

// Add initial reference. Normally removed in AdapterHalt.
adapter->RefCount = 1;

Expand Down Expand Up @@ -954,6 +957,63 @@ Return Value:
DEBUGP (("[TAP] <-- AdapterHalt\n"));
}

VOID
tapWaitForReceiveNblInFlightCountZeroEvent(
__in PTAP_ADAPTER_CONTEXT Adapter
)
{
LONG nblCount;

//
// Wait until higher-level protocol has returned all NBLs
// to the driver.
//

// Add one NBL "bias" to insure allow event to be reset safely.
nblCount = NdisInterlockedIncrement(&Adapter->ReceiveNblInFlightCount);
ASSERT(nblCount > 0);
NdisResetEvent(&Adapter->ReceiveNblInFlightCountZeroEvent);

//
// Now remove the bias and wait for the ReceiveNblInFlightCountZeroEvent
// if the count returned is not zero.
//
nblCount = NdisInterlockedDecrement(&Adapter->ReceiveNblInFlightCount);
ASSERT(nblCount >= 0);

if (nblCount)
{
LARGE_INTEGER startTime, currentTime;

NdisGetSystemUpTimeEx(&startTime);

for (;;)
{
BOOLEAN waitResult = NdisWaitEvent(
&Adapter->ReceiveNblInFlightCountZeroEvent,
TAP_WAIT_POLL_LOOP_TIMEOUT
);

NdisGetSystemUpTimeEx(&currentTime);

if (waitResult)
{
break;
}

DEBUGP(("[%s] Waiting for %d in-flight receive NBLs to be returned.\n",
MINIPORT_INSTANCE_ID(Adapter),
Adapter->ReceiveNblInFlightCount
));
}

DEBUGP(("[%s] Waited %d ms for all in-flight NBLs to be returned.\n",
MINIPORT_INSTANCE_ID(Adapter),
(currentTime.LowPart - startTime.LowPart)
));
}
}

NDIS_STATUS
AdapterPause(
__in NDIS_HANDLE MiniportAdapterContext,
Expand Down Expand Up @@ -1016,6 +1076,21 @@ Return Value:
adapter->Locked.AdapterState = MiniportPausingState;
tapAdapterReleaseLock(adapter,FALSE);

//
// Stop the flow of network data through the receive path
// ------------------------------------------------------
// In the Pausing and Paused state tapAdapterSendAndReceiveReady
// will prevent new calls to NdisMIndicateReceiveNetBufferLists
// to indicate additional receive NBLs to the host.
//
// However, there may be some in-flight NBLs owned by the driver
// that have been indicated to the host but have not yet been
// returned.
//
// Wait here for all in-flight receive indications to be returned.
//
tapWaitForReceiveNblInFlightCountZeroEvent(adapter);

//
// Stop the flow of network data through the send path
// ---------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions src/adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ typedef struct _TAP_ADAPTER_CONTEXT
// NBL pool for making TAP receive indications.
NDIS_HANDLE ReceiveNblPool;

volatile LONG ReceiveNblInFlightCount;
#define TAP_WAIT_POLL_LOOP_TIMEOUT 3000 // 3 seconds
NDIS_EVENT ReceiveNblInFlightCountZeroEvent;

// Info for point-to-point mode
BOOLEAN m_tun;
IPADDR m_localIP;
Expand Down
52 changes: 44 additions & 8 deletions src/rxpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
VOID
tapFreeReceiveNetBufferList(
__in PTAP_ADAPTER_CONTEXT Adapter,
__in PNET_BUFFER_LIST NetBufferList // Only one NB here...
__in PNET_BUFFER_LIST NetBufferList, // Only one NB here...
__in BOOLEAN DecrementInflight
)
{
ULONG frameType, netBufferCount, byteCount;
Expand Down Expand Up @@ -130,6 +131,17 @@ tapFreeReceiveNetBufferList(
NdisFreeMdl(mdl);
}

if (DecrementInflight)
{
// Decrement in-flight receive NBL count.
LONG nblCount = NdisInterlockedDecrement(&Adapter->ReceiveNblInFlightCount);
ASSERT(nblCount >= 0);
if (0 == nblCount)
{
NdisSetEvent(&Adapter->ReceiveNblInFlightCountZeroEvent);
}
}

// Free the NBL
NdisFreeNetBufferList(NetBufferList);
}
Expand Down Expand Up @@ -224,7 +236,7 @@ IndicateReceivePacket(

if(netBufferList != NULL)
{
ULONG receiveFlags = NDIS_RECEIVE_FLAGS_RESOURCES;
ULONG receiveFlags = 0;

NET_BUFFER_LIST_NEXT_NBL(netBufferList) = NULL; // Only one NBL

Expand All @@ -240,6 +252,10 @@ IndicateReceivePacket(
netBufferList->MiniportReserved[0] = NULL;
netBufferList->MiniportReserved[1] = NULL;

// Increment in-flight receive NBL count.
LONG nblCount = NdisInterlockedIncrement(&Adapter->ReceiveNblInFlightCount);
ASSERT(nblCount > 0);

netBufferList->SourceHandle = Adapter->MiniportAdapterHandle;

//
Expand All @@ -256,8 +272,6 @@ IndicateReceivePacket(
receiveFlags
);

tapFreeReceiveNetBufferList(Adapter->MiniportAdapterHandle, netBufferList);

return;
}
else
Expand Down Expand Up @@ -292,11 +306,33 @@ AdapterReturnNetBufferLists(
__in NDIS_HANDLE MiniportAdapterContext,
__in PNET_BUFFER_LIST NetBufferLists,
__in ULONG ReturnFlags
)
)
{
PTAP_ADAPTER_CONTEXT adapter = (PTAP_ADAPTER_CONTEXT )MiniportAdapterContext;
PTAP_ADAPTER_CONTEXT adapter = (PTAP_ADAPTER_CONTEXT)MiniportAdapterContext;
PNET_BUFFER_LIST currentNbl;

DEBUGP(("[%s] Unexpected AdapterReturnNetBufferLists() call\n", MINIPORT_INSTANCE_ID(adapter)));
UNREFERENCED_PARAMETER(ReturnFlags);

//
// Process each NBL individually
//
currentNbl = NetBufferLists;
while (currentNbl)
{
PNET_BUFFER_LIST nextNbl;

nextNbl = NET_BUFFER_LIST_NEXT_NBL(currentNbl);
NET_BUFFER_LIST_NEXT_NBL(currentNbl) = NULL;

// Complete write IRP and free NBL and associated resources.
tapFreeReceiveNetBufferList(
adapter,
currentNbl,
TRUE);

// Move to next NBL
currentNbl = nextNbl;
}
}

static PVOID
Expand Down Expand Up @@ -527,7 +563,7 @@ TapSharedSendPacket(
NDIS_RECEIVE_FLAGS_RESOURCES // ReceiveFlags
);

tapFreeReceiveNetBufferList(Adapter->MiniportAdapterHandle, netBufferList);
tapFreeReceiveNetBufferList(Adapter->MiniportAdapterHandle, netBufferList, FALSE);

return STATUS_SUCCESS;
}
Expand Down
8 changes: 4 additions & 4 deletions version.m4
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ dnl define the TAP version
define([PRODUCT_NAME], [TAP-Windows])
define([PRODUCT_PACKAGE_NAME], [tap-windows])
define([PRODUCT_PUBLISHER], [OpenVPN Technologies, Inc.])
define([PRODUCT_VERSION], [9.24.7])
define([PRODUCT_VERSION_RESOURCE], [9,24,7,601])
define([PRODUCT_VERSION], [9.24.8])
define([PRODUCT_VERSION_RESOURCE], [9,24,8,601])
define([PRODUCT_TAP_WIN_COMPONENT_ID], [tap0901])
define([PRODUCT_TAP_WIN_MAJOR], [9])
define([PRODUCT_TAP_WIN_MINOR], [24])
define([PRODUCT_TAP_WIN_REVISION], [7])
define([PRODUCT_TAP_WIN_REVISION], [8])
define([PRODUCT_TAP_WIN_BUILD], [601])
define([PRODUCT_TAP_WIN_PROVIDER], [TAP-Windows Provider V9])
define([PRODUCT_TAP_WIN_CHARACTERISTICS], [0x1])
define([PRODUCT_TAP_WIN_DEVICE_DESCRIPTION], [TAP-Windows Adapter V9])
define([PRODUCT_TAP_WIN_RELDATE], [04/12/2022])
define([PRODUCT_TAP_WIN_RELDATE], [11/18/2022])

0 comments on commit b2aeda5

Please sign in to comment.