[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [win-pv-devel] [PATCH 01/20] Add SUSPEND interface IOCTLs
> -----Original Message----- > From: win-pv-devel [mailto:win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx] On > Behalf Of Owen Smith > Sent: 24 May 2016 15:21 > To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Owen Smith > Subject: [win-pv-devel] [PATCH 01/20] Add SUSPEND interface IOCTLs > > * GetCount : returns current suspend count, changes over suspends > * Register : register an event that is set on resume from suspend > * Deregister: deregister the resume-from-suspend event > > Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> > --- > include/xeniface_ioctls.h | 37 +++++++ > src/xeniface/fdo.c | 12 +++ > src/xeniface/fdo.h | 3 + > src/xeniface/ioctl_suspend.c | 223 > +++++++++++++++++++++++++++++++++++++++ > src/xeniface/ioctls.c | 34 +++++- > src/xeniface/ioctls.h | 46 ++++++++ > vs2012/xeniface/xeniface.vcxproj | 1 + > vs2013/xeniface/xeniface.vcxproj | 1 + > 8 files changed, 355 insertions(+), 2 deletions(-) > create mode 100644 src/xeniface/ioctl_suspend.c > > diff --git a/include/xeniface_ioctls.h b/include/xeniface_ioctls.h > index 17beaa1..dc53e6b 100644 > --- a/include/xeniface_ioctls.h > +++ b/include/xeniface_ioctls.h > @@ -323,4 +323,41 @@ typedef struct > _XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES_IN { > ULONG RequestId; /*! Request ID used in the corresponding > IOCTL_XENIFACE_GNTTAB_MAP_FOREIGN_PAGES call */ > } XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES_IN, > *PXENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES_IN; > > +/*! \brief Gets the current suspend count. > + > + Input: None > + > + Output: ULONG > +*/ > +#define IOCTL_XENIFACE_SUSPEND_GET_COUNT \ > + CTL_CODE(FILE_DEVICE_UNKNOWN, 0x830, METHOD_BUFFERED, > FILE_ANY_ACCESS) > + > +/*! \brief Registers an event which is signalled on resume-from-suspend > + > + Input: XENIFACE_SUSPEND_REGISTER_IN > + > + Output: XENIFACE_SUSPEND_REGISTER_OUT > +*/ > +#define IOCTL_XENIFACE_SUSPEND_REGISTER \ > + CTL_CODE(FILE_DEVICE_UNKNOWN, 0x831, METHOD_BUFFERED, > FILE_ANY_ACCESS) > + > +/*! \brief Input for IOCTL_XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES This comment needs fixing. > */ > +typedef struct _XENIFACE_SUSPEND_REGISTER_IN { > + HANDLE Event; /*!< Handle to an event object that will receive suspend > notifications */ > +} XENIFACE_SUSPEND_REGISTER_IN, > *PXENIFACE_SUSPEND_REGISTER_IN; > + > +/*! \brief Input for IOCTL_XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES > */ So, does this. > +typedef struct _XENIFACE_SUSPEND_REGISTER_OUT { > + PVOID Context; /*!< Handle to the suspend event */ > +} XENIFACE_SUSPEND_REGISTER_OUT, > *PXENIFACE_SUSPEND_REGISTER_OUT; > + > +/*! \brief Deregisters an event which is signalled on resume-from-suspend > + > + Input: XENIFACE_SUSPEND_REGISTER_OUT > + > + Output: None > +*/ > +#define IOCTL_XENIFACE_SUSPEND_DEREGISTER \ > + CTL_CODE(FILE_DEVICE_UNKNOWN, 0x832, METHOD_BUFFERED, > FILE_ANY_ACCESS) > + > #endif // _XENIFACE_IOCTLS_H_ > diff --git a/src/xeniface/fdo.c b/src/xeniface/fdo.c > index fa14b5b..6d17189 100644 > --- a/src/xeniface/fdo.c > +++ b/src/xeniface/fdo.c > @@ -908,6 +908,7 @@ FdoSuspendCallbackLate( > ASSERT(NT_SUCCESS(status)); > > WmiFireSuspendEvent(Fdo); > + SuspendEventFire(Fdo); > } > > static DECLSPEC_NOINLINE NTSTATUS > @@ -2570,6 +2571,9 @@ FdoCreate( > KeInitializeSpinLock(&Fdo->EvtchnLock); > InitializeListHead(&Fdo->EvtchnList); > > + KeInitializeSpinLock(&Fdo->SuspendLock); > + InitializeListHead(&Fdo->SuspendList); > + > KeInitializeSpinLock(&Fdo->IrpQueueLock); > InitializeListHead(&Fdo->IrpList); > > @@ -2602,6 +2606,10 @@ fail15: > RtlZeroMemory(&Fdo->IrpList, sizeof (LIST_ENTRY)); > RtlZeroMemory(&Fdo->IrpQueueLock, sizeof (KSPIN_LOCK)); > > + ASSERT(IsListEmpty(&Fdo->SuspendList)); > + RtlZeroMemory(&Fdo->SuspendList, sizeof (LIST_ENTRY)); > + RtlZeroMemory(&Fdo->SuspendLock, sizeof (KSPIN_LOCK)); > + > ASSERT(IsListEmpty(&Fdo->EvtchnList)); > RtlZeroMemory(&Fdo->EvtchnList, sizeof (LIST_ENTRY)); > RtlZeroMemory(&Fdo->EvtchnLock, sizeof (KSPIN_LOCK)); > @@ -2724,6 +2732,10 @@ FdoDestroy( > RtlZeroMemory(&Fdo->IrpQueueLock, sizeof (KSPIN_LOCK)); > RtlZeroMemory(&Fdo->IrpQueue, sizeof (IO_CSQ)); > > + ASSERT(IsListEmpty(&Fdo->SuspendList)); > + RtlZeroMemory(&Fdo->SuspendList, sizeof (LIST_ENTRY)); > + RtlZeroMemory(&Fdo->SuspendLock, sizeof (KSPIN_LOCK)); > + > ASSERT(IsListEmpty(&Fdo->EvtchnList)); > RtlZeroMemory(&Fdo->EvtchnList, sizeof (LIST_ENTRY)); > RtlZeroMemory(&Fdo->EvtchnLock, sizeof (KSPIN_LOCK)); > diff --git a/src/xeniface/fdo.h b/src/xeniface/fdo.h > index 6cd628c..c82d2bf 100644 > --- a/src/xeniface/fdo.h > +++ b/src/xeniface/fdo.h > @@ -92,6 +92,9 @@ typedef struct _XENIFACE_FDO { > > KSPIN_LOCK GnttabCacheLock; > > + KSPIN_LOCK SuspendLock; > + LIST_ENTRY SuspendList; > + > IO_CSQ IrpQueue; > KSPIN_LOCK IrpQueueLock; > LIST_ENTRY IrpList; > diff --git a/src/xeniface/ioctl_suspend.c b/src/xeniface/ioctl_suspend.c > new file mode 100644 > index 0000000..bb6a1ad > --- /dev/null > +++ b/src/xeniface/ioctl_suspend.c > @@ -0,0 +1,223 @@ > +/* Copyright (c) Citrix Systems Inc. > + * Copyright (c) Rafal Wojdyla <omeg@xxxxxxxxxxxxxxxxxxxxxx> Delete this copyright. Paul > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, > + * with or without modification, are permitted provided > + * that the following conditions are met: > + * > + * * Redistributions of source code must retain the above > + * copyright notice, this list of conditions and the > + * following disclaimer. > + * * Redistributions in binary form must reproduce the above > + * copyright notice, this list of conditions and the > + * following disclaimer in the documentation and/or other > + * materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND > + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, > + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR > + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, > + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR > + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, > + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING > + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > + * SUCH DAMAGE. > + */ > + > +#include "driver.h" > +#include "ioctls.h" > +#include "xeniface_ioctls.h" > +#include "log.h" > + > +DECLSPEC_NOINLINE > +NTSTATUS > +IoctlSuspendGetCount( > + __in PXENIFACE_FDO Fdo, > + __in PCHAR Buffer, > + __in ULONG InLen, > + __in ULONG OutLen, > + __out PULONG_PTR Info > + ) > +{ > + NTSTATUS status; > + PULONG Value; > + > + status = STATUS_INVALID_BUFFER_SIZE; > + if (InLen != 0) > + goto fail1; > + > + if (OutLen != sizeof(ULONG)) > + goto fail2; > + > + Value = (PULONG)Buffer; > + *Value = XENBUS_SUSPEND(GetCount, &Fdo->SuspendInterface); > + *Info = (ULONG_PTR)sizeof(ULONG); > + status = STATUS_SUCCESS; > + > + return status; > + > +fail2: > + XenIfaceDebugPrint(ERROR, "Fail2\n"); > +fail1: > + XenIfaceDebugPrint(ERROR, "Fail1 (%08x)\n", status); > + return status; > +} > + > +DECLSPEC_NOINLINE > +NTSTATUS > +IoctlSuspendRegister( > + __in PXENIFACE_FDO Fdo, > + __in PVOID Buffer, > + __in ULONG InLen, > + __in ULONG OutLen, > + __in PFILE_OBJECT FileObject, > + __out PULONG_PTR Info > + ) > +{ > + NTSTATUS status; > + PXENIFACE_SUSPEND_REGISTER_IN In = Buffer; > + PXENIFACE_SUSPEND_REGISTER_OUT Out = Buffer; > + PXENIFACE_SUSPEND_CONTEXT Context; > + > + status = STATUS_INVALID_BUFFER_SIZE; > + if (InLen != sizeof(XENIFACE_SUSPEND_REGISTER_IN) || > + OutLen != sizeof(XENIFACE_SUSPEND_REGISTER_OUT)) { > + goto fail1; > + } > + > + status = STATUS_NO_MEMORY; > + Context = ExAllocatePoolWithTag(NonPagedPool, > sizeof(XENIFACE_SUSPEND_CONTEXT), XENIFACE_POOL_TAG); > + if (Context == NULL) > + goto fail2; > + > + RtlZeroMemory(Context, sizeof(XENIFACE_SUSPEND_CONTEXT)); > + > + Context->FileObject = FileObject; > + > + status = ObReferenceObjectByHandle(In->Event, > + EVENT_MODIFY_STATE, > + *ExEventObjectType, > + UserMode, > + &Context->Event, > + NULL); > + if (!NT_SUCCESS(status)) > + goto fail3; > + > + XenIfaceDebugPrint(TRACE, "> Suspend Event %p, FO %p\n", In->Event, > FileObject); > + ExInterlockedInsertTailList(&Fdo->SuspendList, &Context->Entry, &Fdo- > >SuspendLock); > + > + Out->Context = Context; > + *Info = sizeof(XENIFACE_SUSPEND_REGISTER_OUT); > + > + return status; > + > +fail3: > + XenIfaceDebugPrint(ERROR, "Fail3\n"); > + RtlZeroMemory(Context, sizeof(XENIFACE_SUSPEND_CONTEXT)); > + ExFreePoolWithTag(Context, XENIFACE_POOL_TAG); > + > +fail2: > + XenIfaceDebugPrint(ERROR, "Fail2\n"); > + > +fail1: > + XenIfaceDebugPrint(ERROR, "Fail1 (%08x)\n", status); > + return status; > +} > + > +_IRQL_requires_max_(DISPATCH_LEVEL) > +VOID > +SuspendFreeEvent( > + __in PXENIFACE_FDO Fdo, > + __inout PXENIFACE_SUSPEND_CONTEXT Context > + ) > +{ > + XenIfaceDebugPrint(TRACE, "Context %p, FO %p\n", > + Context, Context->FileObject); > + > + ObDereferenceObject(Context->Event); > + RtlZeroMemory(Context, sizeof(XENIFACE_SUSPEND_CONTEXT)); > + ExFreePoolWithTag(Context, XENIFACE_POOL_TAG); > +} > + > +DECLSPEC_NOINLINE > +NTSTATUS > +IoctlSuspendDeregister( > + __in PXENIFACE_FDO Fdo, > + __in PVOID Buffer, > + __in ULONG InLen, > + __in ULONG OutLen, > + __in PFILE_OBJECT FileObject > + ) > +{ > + NTSTATUS status; > + PXENIFACE_SUSPEND_REGISTER_OUT In = Buffer; > + PXENIFACE_SUSPEND_CONTEXT Context = NULL; > + KIRQL Irql; > + PLIST_ENTRY Node; > + > + status = STATUS_INVALID_BUFFER_SIZE; > + if (InLen != sizeof(XENIFACE_SUSPEND_REGISTER_OUT) || > + OutLen != 0) { > + goto fail1; > + } > + > + XenIfaceDebugPrint(TRACE, "> Context %p, FO %p\n", In->Context, > FileObject); > + > + KeAcquireSpinLock(&Fdo->SuspendLock, &Irql); > + Node = Fdo->SuspendList.Flink; > + while (Node->Flink != Fdo->SuspendList.Flink) { > + Context = CONTAINING_RECORD(Node, > XENIFACE_SUSPEND_CONTEXT, Entry); > + > + Node = Node->Flink; > + if (Context != In->Context || > + Context->FileObject != FileObject) { > + continue; > + } > + > + RemoveEntryList(&Context->Entry); > + break; > + } > + KeReleaseSpinLock(&Fdo->SuspendLock, Irql); > + > + status = STATUS_NOT_FOUND; > + if (Context == NULL || Context != In->Context) > + goto fail2; > + > + SuspendFreeEvent(Fdo, Context); > + > + return STATUS_SUCCESS; > + > +fail2: > + XenIfaceDebugPrint(ERROR, "Fail2\n"); > + > +fail1: > + XenIfaceDebugPrint(ERROR, "Fail1 (%08x)\n", status); > + return status; > +} > + > +VOID > +SuspendEventFire( > + __in PXENIFACE_FDO Fdo > + ) > +{ > + KIRQL Irql; > + PLIST_ENTRY Node; > + PXENIFACE_SUSPEND_CONTEXT Context; > + > + KeAcquireSpinLock(&Fdo->SuspendLock, &Irql); > + Node = Fdo->SuspendList.Flink; > + while (Node->Flink != Fdo->SuspendList.Flink) { > + Context = CONTAINING_RECORD(Node, > XENIFACE_SUSPEND_CONTEXT, Entry); > + > + KeSetEvent(Context->Event, IO_NO_INCREMENT, FALSE); > + > + Node = Node->Flink; > + } > + KeReleaseSpinLock(&Fdo->SuspendLock, Irql); > +} > \ No newline at end of file > diff --git a/src/xeniface/ioctls.c b/src/xeniface/ioctls.c > index a8a5538..c6d471d 100644 > --- a/src/xeniface/ioctls.c > +++ b/src/xeniface/ioctls.c > @@ -94,11 +94,28 @@ XenIfaceCleanup( > ) > { > PLIST_ENTRY Node; > - PXENIFACE_STORE_CONTEXT StoreContext; > - PXENIFACE_EVTCHN_CONTEXT EvtchnContext; > + PXENIFACE_SUSPEND_CONTEXT SuspendContext; > + PXENIFACE_STORE_CONTEXT StoreContext; > + PXENIFACE_EVTCHN_CONTEXT EvtchnContext; > KIRQL Irql; > LIST_ENTRY ToFree; > > + // suspend events > + KeAcquireSpinLock(&Fdo->SuspendLock, &Irql); > + Node = Fdo->SuspendList.Flink; > + while (Node->Flink != Fdo->SuspendList.Flink) { > + SuspendContext = CONTAINING_RECORD(Node, > XENIFACE_SUSPEND_CONTEXT, Entry); > + > + Node = Node->Flink; > + if (SuspendContext->FileObject != FileObject) > + continue; > + > + XenIfaceDebugPrint(TRACE, "Suspend context %p\n", > SuspendContext); > + RemoveEntryList(&SuspendContext->Entry); > + SuspendFreeEvent(Fdo, SuspendContext); > + } > + KeReleaseSpinLock(&Fdo->SuspendLock, Irql); > + > // store watches > KeAcquireSpinLock(&Fdo->StoreWatchLock, &Irql); > Node = Fdo->StoreWatchList.Flink; > @@ -227,6 +244,19 @@ XenIfaceIoctl( > status = IoctlGnttabUnmapForeignPages(Fdo, Buffer, InLen, OutLen); > break; > > + // suspend > + case IOCTL_XENIFACE_SUSPEND_GET_COUNT: > + status = IoctlSuspendGetCount(Fdo, Buffer, InLen, OutLen, &Irp- > >IoStatus.Information); > + break; > + > + case IOCTL_XENIFACE_SUSPEND_REGISTER: > + status = IoctlSuspendRegister(Fdo, Buffer, InLen, OutLen, Stack- > >FileObject, &Irp->IoStatus.Information); > + break; > + > + case IOCTL_XENIFACE_SUSPEND_DEREGISTER: > + status = IoctlSuspendDeregister(Fdo, Buffer, InLen, OutLen, Stack- > >FileObject); > + break; > + > default: > status = STATUS_INVALID_DEVICE_REQUEST; > break; > diff --git a/src/xeniface/ioctls.h b/src/xeniface/ioctls.h > index da273ce..005aea5 100644 > --- a/src/xeniface/ioctls.h > +++ b/src/xeniface/ioctls.h > @@ -91,6 +91,12 @@ typedef struct _XENIFACE_MAP_CONTEXT { > PMDL Mdl; > } XENIFACE_MAP_CONTEXT, *PXENIFACE_MAP_CONTEXT; > > +typedef struct _XENIFACE_SUSPEND_CONTEXT { > + LIST_ENTRY Entry; > + PKEVENT Event; > + PVOID FileObject; > +} XENIFACE_SUSPEND_CONTEXT, *PXENIFACE_SUSPEND_CONTEXT; > + > NTSTATUS > __CaptureUserBuffer( > __in PVOID Buffer, > @@ -363,5 +369,45 @@ GnttabFreeMap( > __inout PXENIFACE_MAP_CONTEXT Context > ); > > +NTSTATUS > +IoctlSuspendGetCount( > + __in PXENIFACE_FDO Fdo, > + __in PCHAR Buffer, > + __in ULONG InLen, > + __in ULONG OutLen, > + __out PULONG_PTR Info > + ); > + > +NTSTATUS > +IoctlSuspendRegister( > + __in PXENIFACE_FDO Fdo, > + __in PVOID Buffer, > + __in ULONG InLen, > + __in ULONG OutLen, > + __in PFILE_OBJECT FileObject, > + __out PULONG_PTR Info > + ); > + > +NTSTATUS > +IoctlSuspendDeregister( > + __in PXENIFACE_FDO Fdo, > + __in PVOID Buffer, > + __in ULONG InLen, > + __in ULONG OutLen, > + __in PFILE_OBJECT FileObject > + ); > + > +VOID > +SuspendEventFire( > + __in PXENIFACE_FDO Fdo > + ); > + > +_IRQL_requires_max_(DISPATCH_LEVEL) > +VOID > +SuspendFreeEvent( > + __in PXENIFACE_FDO Fdo, > + __inout PXENIFACE_SUSPEND_CONTEXT Context > + ); > + > #endif // _IOCTLS_H_ > > diff --git a/vs2012/xeniface/xeniface.vcxproj > b/vs2012/xeniface/xeniface.vcxproj > index c57e2a2..aec3533 100644 > --- a/vs2012/xeniface/xeniface.vcxproj > +++ b/vs2012/xeniface/xeniface.vcxproj > @@ -82,6 +82,7 @@ > <ClCompile Include="..\..\src\xeniface\ioctl_evtchn.c" /> > <ClCompile Include="..\..\src\xeniface\ioctl_gnttab.c" /> > <ClCompile Include="..\..\src\xeniface\ioctl_store.c" /> > + <ClCompile Include="..\..\src\xeniface\ioctl_suspend.c" /> > <ClCompile Include="..\..\src\xeniface\irp_queue.c" /> > </ItemGroup> > <ItemGroup> > diff --git a/vs2013/xeniface/xeniface.vcxproj > b/vs2013/xeniface/xeniface.vcxproj > index 08ac3a1..b324d9c 100644 > --- a/vs2013/xeniface/xeniface.vcxproj > +++ b/vs2013/xeniface/xeniface.vcxproj > @@ -134,6 +134,7 @@ > <ClCompile Include="..\..\src\xeniface\ioctl_evtchn.c" /> > <ClCompile Include="..\..\src\xeniface\ioctl_gnttab.c" /> > <ClCompile Include="..\..\src\xeniface\ioctl_store.c" /> > + <ClCompile Include="..\..\src\xeniface\ioctl_suspend.c" /> > <ClCompile Include="..\..\src\xeniface\irp_queue.c" /> > </ItemGroup> > <ItemGroup> > -- > 1.9.4.msysgit.1 > > > _______________________________________________ > win-pv-devel mailing list > win-pv-devel@xxxxxxxxxxxxxxxxxxxx > http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |