From: Owen Smith Date: Mon, 11 Sep 2017 20:04:22 +0000 (-0700) Subject: Destroy all handles on FdoD0ToD3 X-Git-Tag: 9.0.0-rc1~34 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=84b583523c64e5e778ef261a96c7db3fe0f551af;p=pvdrivers%2Fwin%2Fxencons.git Destroy all handles on FdoD0ToD3 Since the StreamWorker holds a reference to the XENBUS_CONS interface, xenbus will BUG_ON if the handles are not cleaned up before power down. The service should close all handles in response to a DBT_DEVICEQUERYREMOVE notification, but this may not be issued on system power down. Signed-off-by: Owen Smith Added missing UNREFERENCED_PARAMETER() to fix build failure. Signed-off-by: Paul Durrant --- diff --git a/src/xencons/fdo.c b/src/xencons/fdo.c index 5992776..94465a5 100644 --- a/src/xencons/fdo.c +++ b/src/xencons/fdo.c @@ -902,6 +902,77 @@ fail1: return status; } +static FORCEINLINE VOID +__FdoDestroyHandle( + IN PXENCONS_FDO Fdo, + IN PFDO_HANDLE Handle + ) +{ + UNREFERENCED_PARAMETER(Fdo); + + Trace("%p\n", Handle->FileObject); + + RtlZeroMemory(&Handle->ListEntry, sizeof (LIST_ENTRY)); + + StreamDestroy(Handle->Stream); + Handle->Stream = NULL; + + Handle->FileObject = NULL; + + ASSERT(IsZeroMemory(Handle, sizeof (FDO_HANDLE))); + __FdoFree(Handle); +} + +static VOID +FdoDestroyHandle( + IN PXENCONS_FDO Fdo, + IN PFDO_HANDLE Handle + ) +{ + KIRQL Irql; + + KeAcquireSpinLock(&Fdo->HandleLock, &Irql); + RemoveEntryList(&Handle->ListEntry); + KeReleaseSpinLock(&Fdo->HandleLock, Irql); + + __FdoDestroyHandle(Fdo, Handle); +} + +static VOID +FdoDestroyAllHandles( + IN PXENCONS_FDO Fdo + ) +{ + KIRQL Irql; + LIST_ENTRY List; + PLIST_ENTRY ListEntry; + PFDO_HANDLE Handle; + + InitializeListHead(&List); + + KeAcquireSpinLock(&Fdo->HandleLock, &Irql); + + ListEntry = Fdo->HandleList.Flink; + if (!IsListEmpty(&Fdo->HandleList)) { + RemoveEntryList(&Fdo->HandleList); + InitializeListHead(&Fdo->HandleList); + AppendTailList(&List, ListEntry); + } + + KeReleaseSpinLock(&Fdo->HandleLock, Irql); + + while (!IsListEmpty(&List)) { + ListEntry = RemoveHeadList(&List); + ASSERT3P(ListEntry, !=, &List); + + Handle = CONTAINING_RECORD(ListEntry, + FDO_HANDLE, + ListEntry); + + __FdoDestroyHandle(Fdo, Handle); + } +} + // This function must not touch pageable code or data static DECLSPEC_NOINLINE VOID FdoD0ToD3( @@ -920,6 +991,8 @@ FdoD0ToD3( #pragma prefast(suppress:28123) (VOID) IoSetDeviceInterfaceState(&Dx->Link, FALSE); + FdoDestroyAllHandles(Fdo); + PowerState.DeviceState = PowerDeviceD3; PoSetPowerState(Fdo->Dx->DeviceObject, DevicePowerState, @@ -2175,31 +2248,6 @@ fail1: return NULL; } -static VOID -FdoDestroyHandle( - IN PXENCONS_FDO Fdo, - IN PFDO_HANDLE Handle - ) -{ - KIRQL Irql; - - KeAcquireSpinLock(&Fdo->HandleLock, &Irql); - RemoveEntryList(&Handle->ListEntry); - KeReleaseSpinLock(&Fdo->HandleLock, Irql); - - RtlZeroMemory(&Handle->ListEntry, sizeof (LIST_ENTRY)); - - Trace("%p\n", Handle->FileObject); - - StreamDestroy(Handle->Stream); - Handle->Stream = NULL; - - Handle->FileObject = NULL; - - ASSERT(IsZeroMemory(Handle, sizeof (FDO_HANDLE))); - __FdoFree(Handle); -} - static DECLSPEC_NOINLINE NTSTATUS FdoDispatchCreate( IN PXENCONS_FDO Fdo,