|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 09/14] add boilerplate ring
From: Owen Smith <owen.smith@xxxxxxxxxx>
Also queries for gnttab and evtchn interface and adds those headers
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
include/cache_interface.h | 233 +++++++++++++++++
include/evtchn_interface.h | 357 +++++++++++++++++++++++++
include/gnttab_interface.h | 287 ++++++++++++++++++++
src/xencons/fdo.c | 42 ++-
src/xencons/fdo.h | 4 +
src/xencons/frontend.c | 61 +++--
src/xencons/ring.c | 578 +++++++++++++++++++++++++++++++++++++++++
src/xencons/ring.h | 78 ++++++
vs2015/xencons/xencons.vcxproj | 1 +
9 files changed, 1621 insertions(+), 20 deletions(-)
create mode 100755 include/cache_interface.h
create mode 100755 include/evtchn_interface.h
create mode 100755 include/gnttab_interface.h
create mode 100755 src/xencons/ring.c
create mode 100755 src/xencons/ring.h
diff --git a/include/cache_interface.h b/include/cache_interface.h
new file mode 100755
index 0000000..dae3ac6
--- /dev/null
+++ b/include/cache_interface.h
@@ -0,0 +1,233 @@
+/* Copyright (c) Citrix Systems Inc.
+ * 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.
+ */
+
+/*! \file cache_interface.h
+ \brief XENBUS CACHE Interface
+
+ This interface provides access to XENBUS's object cache
+ implementation.
+*/
+
+#ifndef _XENBUS_CACHE_INTERFACE_H
+#define _XENBUS_CACHE_INTERFACE_H
+
+#ifndef _WINDLL
+
+/*! \typedef XENBUS_CACHE
+ \brief Cache handle
+*/
+typedef struct _XENBUS_CACHE XENBUS_CACHE, *PXENBUS_CACHE;
+
+/*! \typedef XENBUS_CACHE_ACQUIRE
+ \brief Acquire a reference to the CACHE interface
+
+ \param Interface The interface header
+*/
+typedef NTSTATUS
+(*XENBUS_CACHE_ACQUIRE)(
+ IN PINTERFACE Interface
+ );
+
+/*! \typedef XENBUS_CACHE_RELEASE
+ \brief Release a reference to the CACHE interface
+
+ \param Interface The interface header
+*/
+typedef VOID
+(*XENBUS_CACHE_RELEASE)(
+ IN PINTERFACE Interface
+ );
+
+/*! \typedef XENBUS_CACHE_CTOR
+ \brief Object creator callback
+
+ \param Argument Context \a Argument supplied to \a XENBUS_CACHE_CREATE
+ \param Object Newly allocated object
+
+ This callback is invoked just after a new object is allocated and may
+ be used to initialize any object data prior to its insertion into the
+ cache.
+*/
+typedef NTSTATUS
+(*XENBUS_CACHE_CTOR)(
+ IN PVOID Argument,
+ IN PVOID Object
+ );
+
+/*! \typedef XENBUS_CACHE_DTOR
+ \brief Object destructor callback
+
+ \param Argument Context \a Argument supplied to \a XENBUS_CACHE_CREATE
+ \param Object Object about to be freed
+
+ This callback is invoked just after an object is removed from the
+ cache and before it is freed and may be used to tear down any object data.
+*/
+typedef VOID
+(*XENBUS_CACHE_DTOR)(
+ IN PVOID Argument,
+ IN PVOID Object
+ );
+
+/*! \typedef XENBUS_CACHE_ACQUIRE_LOCK
+ \brief Cache lock callback
+
+ \param Argument Context \a Argument supplied to \a XENBUS_CACHE_CREATE
+
+ This callback is invoked if the cache implementation requires mutual
+ exclusion.
+*/
+typedef VOID
+(*XENBUS_CACHE_ACQUIRE_LOCK)(
+ IN PVOID Argument
+ );
+
+/*! \typedef XENBUS_CACHE_RELEASE_LOCK
+ \brief Cache unlock callback
+
+ \param Argument Context \a Argument supplied to \a XENBUS_CACHE_CREATE
+
+ This callback is invoked to release the mutual exclusion lock acquired
+ by a previous invocation of \a XENBUS_CACHE_ACQUIRE_LOCK.
+*/
+typedef VOID
+(*XENBUS_CACHE_RELEASE_LOCK)(
+ IN PVOID Argument
+ );
+
+/*! \typedef XENBUS_CACHE_CREATE
+ \brief Create a cache of objects of the given \a Size
+
+ \param Interface The interface header
+ \param Name A name for the cache which will be used in debug output
+ \param Size The size of each object in bytes
+ \param Reservation The target minimum population of the cache
+ \param Ctor A callback which is invoked when a new object created
+ \param Dtor A callback which is invoked when an object is destroyed
+ \param AcquireLock A callback invoked to acquire a spinlock
+ \param ReleaseLock A callback invoked to release the spinlock
+ \param Argument An optional context argument passed to the callbacks
+ \param Cache A pointer to a cache handle to be initialized
+
+ If a non-zero \a Reservation is specified then this method will fail
+ unless that number of objects can be immediately created.
+*/
+typedef NTSTATUS
+(*XENBUS_CACHE_CREATE)(
+ IN PINTERFACE Interface,
+ IN const CHAR *Name,
+ IN ULONG Size,
+ IN ULONG Reservation,
+ IN XENBUS_CACHE_CTOR Ctor,
+ IN XENBUS_CACHE_DTOR Dtor,
+ IN XENBUS_CACHE_ACQUIRE_LOCK AcquireLock,
+ IN XENBUS_CACHE_RELEASE_LOCK ReleaseLock,
+ IN PVOID Argument OPTIONAL,
+ OUT PXENBUS_CACHE *Cache
+ );
+
+/*! \typedef XENBUS_CACHE_GET
+ \brief Get an object from a \a Cache
+
+ \param Interface The interface header
+ \param Cache The cache handle
+ \param Locked If mutually exclusive access to the cache is already
+ guaranteed then set this to TRUE
+*/
+typedef PVOID
+(*XENBUS_CACHE_GET)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_CACHE Cache,
+ IN BOOLEAN Locked
+ );
+
+/*! \typedef XENBUS_CACHE_PUT
+ \brief Return an object to a \a Cache
+
+ \param Interface The interface header
+ \param Cache The cache handle
+ \param Locked If mutually exclusive access to the cache is already
+ guaranteed then set this to TRUE
+*/
+typedef VOID
+(*XENBUS_CACHE_PUT)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_CACHE Cache,
+ IN PVOID Object,
+ IN BOOLEAN Locked
+ );
+
+/*! \typedef XENBUS_CACHE_DESTROY
+ \brief Destroy a \a Cache
+
+ \param Interface The interface header
+ \param Cache The cache handle
+
+ All objects must have been returned to the cache prior to destruction
+*/
+typedef VOID
+(*XENBUS_CACHE_DESTROY)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_CACHE Cache
+ );
+
+// {A98DFD78-416A-4949-92A5-E084F2F4B44E}
+DEFINE_GUID(GUID_XENBUS_CACHE_INTERFACE,
+0xa98dfd78, 0x416a, 0x4949, 0x92, 0xa5, 0xe0, 0x84, 0xf2, 0xf4, 0xb4, 0x4e);
+
+/*! \struct _XENBUS_CACHE_INTERFACE_V1
+ \brief CACHE interface version 1
+ \ingroup interfaces
+*/
+struct _XENBUS_CACHE_INTERFACE_V1 {
+ INTERFACE Interface;
+ XENBUS_CACHE_ACQUIRE CacheAcquire;
+ XENBUS_CACHE_RELEASE CacheRelease;
+ XENBUS_CACHE_CREATE CacheCreate;
+ XENBUS_CACHE_GET CacheGet;
+ XENBUS_CACHE_PUT CachePut;
+ XENBUS_CACHE_DESTROY CacheDestroy;
+};
+
+typedef struct _XENBUS_CACHE_INTERFACE_V1 XENBUS_CACHE_INTERFACE,
*PXENBUS_CACHE_INTERFACE;
+
+/*! \def XENBUS_CACHE
+ \brief Macro at assist in method invocation
+*/
+#define XENBUS_CACHE(_Method, _Interface, ...) \
+ (_Interface)->Cache ## _Method((PINTERFACE)(_Interface), __VA_ARGS__)
+
+#endif // _WINDLL
+
+#define XENBUS_CACHE_INTERFACE_VERSION_MIN 1
+#define XENBUS_CACHE_INTERFACE_VERSION_MAX 1
+
+#endif // _XENBUS_CACHE_INTERFACE_H
diff --git a/include/evtchn_interface.h b/include/evtchn_interface.h
new file mode 100755
index 0000000..068a697
--- /dev/null
+++ b/include/evtchn_interface.h
@@ -0,0 +1,357 @@
+/* Copyright (c) Citrix Systems Inc.
+ * 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.
+ */
+
+/*! \file evtchn_interface.h
+ \brief XENBUS EVTCHN Interface
+
+ This interface provides access to hypervisor event channels
+*/
+
+#ifndef _XENBUS_EVTCHN_INTERFACE_H
+#define _XENBUS_EVTCHN_INTERFACE_H
+
+#ifndef _WINDLL
+
+/*! \enum _XENBUS_EVTCHN_TYPE
+ \brief Event channel type to be opened
+*/
+typedef enum _XENBUS_EVTCHN_TYPE {
+ XENBUS_EVTCHN_TYPE_INVALID = 0,
+ XENBUS_EVTCHN_TYPE_FIXED, /*!< Fixed */
+ XENBUS_EVTCHN_TYPE_UNBOUND, /*!< Unbound */
+ XENBUS_EVTCHN_TYPE_INTER_DOMAIN, /*!< Interdomain */
+ XENBUS_EVTCHN_TYPE_VIRQ /*!< VIRQ */
+} XENBUS_EVTCHN_TYPE, *PXENBUS_EVTCHN_TYPE;
+
+/*! \typedef XENBUS_EVTCHN_CHANNEL
+ \brief Event channel handle
+*/
+typedef struct _XENBUS_EVTCHN_CHANNEL XENBUS_EVTCHN_CHANNEL,
*PXENBUS_EVTCHN_CHANNEL;
+
+/*! \typedef XENBUS_EVTCHN_ACQUIRE
+ \brief Acquire a reference to the EVTCHN interface
+
+ \param Interface The interface header
+*/
+typedef NTSTATUS
+(*XENBUS_EVTCHN_ACQUIRE)(
+ IN PINTERFACE Interface
+ );
+
+/*! \typedef XENBUS_EVTCHN_RELEASE
+ \brief Release a reference to the EVTCHN interface
+
+ \param Interface The interface header
+*/
+typedef VOID
+(*XENBUS_EVTCHN_RELEASE)(
+ IN PINTERFACE Interface
+ );
+
+/*! \typedef XENBUS_EVTCHN_OPEN
+ \brief Open an event channel
+
+ \param Interface The interface header
+ \param Type The type of event channel to open
+ \param Function The callback function
+ \param Argument An optional context argument passed to the callback
+ \param ... Additional parameters required by \a Type
+
+ \b Fixed:
+ \param LocalPort The local port number of the (already bound) channel
+ \param Mask Set to TRUE if the channel should be automatically masked
before invoking the callback
+
+ \b Unbound:
+ \param RemoteDomain The domid of the remote domain which will bind the
channel
+ \param Mask Set to TRUE if the channel should be automatically masked
before invoking the callback
+
+ \b Interdomain:
+ \param RemoteDomain The domid of the remote domain which has already bound
the channel
+ \param RemotePort The port number bound to the channel in the remote domain
+ \param Mask Set to TRUE if the channel should be automatically masked
before invoking the callback
+
+ \b VIRQ:
+ \param Index The index number of the VIRQ
+
+ \return Event channel handle
+*/
+typedef PXENBUS_EVTCHN_CHANNEL
+(*XENBUS_EVTCHN_OPEN)(
+ IN PINTERFACE Interface,
+ IN XENBUS_EVTCHN_TYPE Type,
+ IN PKSERVICE_ROUTINE Function,
+ IN PVOID Argument OPTIONAL,
+ ...
+ );
+
+/*! \typedef XENBUS_EVTCHN_BIND
+ \brief Bind an event channel to a specific CPU
+
+ \param Interface The interface header
+ \param Channel The channel handle
+ \param Group The group number of the CPU that should handle events
+ \param Number The relative number of the CPU that should handle events
+*/
+typedef NTSTATUS
+(*XENBUS_EVTCHN_BIND)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_EVTCHN_CHANNEL Channel,
+ IN USHORT Group,
+ IN UCHAR Number
+ );
+
+typedef VOID
+(*XENBUS_EVTCHN_UNMASK_V4)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_EVTCHN_CHANNEL Channel,
+ IN BOOLEAN InCallback
+ );
+
+/*! \typedef XENBUS_EVTCHN_UNMASK
+ \brief Unmask an event channel
+
+ \param Interface The interface header
+ \param Channel The channel handle
+ \param InCallback Set to TRUE if this method is invoked in context of the
channel callback
+ \param Force Set to TRUE if the unmask must succeed, otherwise set to
FALSE and the function will return FALSE if the unmask did not complete.
+*/
+typedef BOOLEAN
+(*XENBUS_EVTCHN_UNMASK)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_EVTCHN_CHANNEL Channel,
+ IN BOOLEAN InCallback,
+ IN BOOLEAN Force
+ );
+
+typedef VOID
+(*XENBUS_EVTCHN_SEND_V1)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_EVTCHN_CHANNEL Channel
+ );
+
+/*! \typedef XENBUS_EVTCHN_SEND
+ \brief Send an event to the remote end of the channel
+
+ It is assumed that the domain cannot suspend during this call so
+ IRQL must be >= DISPATCH_LEVEL.
+
+ \param Interface The interface header
+ \param Channel The channel handle
+*/
+typedef VOID
+(*XENBUS_EVTCHN_SEND)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_EVTCHN_CHANNEL Channel
+ );
+
+/*! \typedef XENBUS_EVTCHN_TRIGGER
+ \brief Send an event to the local end of the channel
+
+ \param Interface The interface header
+ \param Channel The channel handle
+*/
+typedef VOID
+(*XENBUS_EVTCHN_TRIGGER)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_EVTCHN_CHANNEL Channel
+ );
+
+/*! \typedef XENBUS_EVTCHN_GET_COUNT
+ \brief Get the number of events received by the channel since it was opened
+
+ \param Interface The interface header
+ \param Channel The channel handle
+ \return The number of events
+*/
+typedef ULONG
+(*XENBUS_EVTCHN_GET_COUNT)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_EVTCHN_CHANNEL Channel
+ );
+
+typedef NTSTATUS
+(*XENBUS_EVTCHN_WAIT_V5)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_EVTCHN_CHANNEL Channel,
+ IN PLARGE_INTEGER Timeout OPTIONAL
+ );
+
+/*! \typedef XENBUS_EVTCHN_WAIT
+ \brief Wait for events to the local end of the channel
+
+ \param Interface The interface header
+ \param Channel The channel handle
+ \param Count The event count to wait for
+ \param Timeout An optional timeout value (similar to
KeWaitForSingleObject(), but non-zero values are allowed at DISPATCH_LEVEL).
+*/
+typedef NTSTATUS
+(*XENBUS_EVTCHN_WAIT)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_EVTCHN_CHANNEL Channel,
+ IN ULONG Count,
+ IN PLARGE_INTEGER Timeout OPTIONAL
+ );
+
+/*! \typedef XENBUS_EVTCHN_GET_PORT
+ \brief Get the local port number bound to the channel
+
+ \param Interface The interface header
+ \param Channel The channel handle
+ \return The port number
+*/
+typedef ULONG
+(*XENBUS_EVTCHN_GET_PORT)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_EVTCHN_CHANNEL Channel
+ );
+
+/*! \typedef XENBUS_EVTCHN_CLOSE
+ \brief Close an event channel
+
+ \param Interface The interface header
+ \param Channel The channel handle
+*/
+typedef VOID
+(*XENBUS_EVTCHN_CLOSE)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_EVTCHN_CHANNEL Channel
+ );
+
+// {BE2440AC-1098-4150-AF4D-452FADCEF923}
+DEFINE_GUID(GUID_XENBUS_EVTCHN_INTERFACE,
+0xbe2440ac, 0x1098, 0x4150, 0xaf, 0x4d, 0x45, 0x2f, 0xad, 0xce, 0xf9, 0x23);
+
+/*! \struct _XENBUS_EVTCHN_INTERFACE_V4
+ \brief EVTCHN interface version 4
+ \ingroup interfaces
+*/
+struct _XENBUS_EVTCHN_INTERFACE_V4 {
+ INTERFACE Interface;
+ XENBUS_EVTCHN_ACQUIRE EvtchnAcquire;
+ XENBUS_EVTCHN_RELEASE EvtchnRelease;
+ XENBUS_EVTCHN_OPEN EvtchnOpen;
+ XENBUS_EVTCHN_BIND EvtchnBind;
+ XENBUS_EVTCHN_UNMASK_V4 EvtchnUnmaskVersion4;
+ XENBUS_EVTCHN_SEND_V1 EvtchnSendVersion1;
+ XENBUS_EVTCHN_TRIGGER EvtchnTrigger;
+ XENBUS_EVTCHN_GET_PORT EvtchnGetPort;
+ XENBUS_EVTCHN_CLOSE EvtchnClose;
+};
+
+/*! \struct _XENBUS_EVTCHN_INTERFACE_V5
+ \brief EVTCHN interface version 5
+ \ingroup interfaces
+*/
+struct _XENBUS_EVTCHN_INTERFACE_V5 {
+ INTERFACE Interface;
+ XENBUS_EVTCHN_ACQUIRE EvtchnAcquire;
+ XENBUS_EVTCHN_RELEASE EvtchnRelease;
+ XENBUS_EVTCHN_OPEN EvtchnOpen;
+ XENBUS_EVTCHN_BIND EvtchnBind;
+ XENBUS_EVTCHN_UNMASK_V4 EvtchnUnmaskVersion4;
+ XENBUS_EVTCHN_SEND_V1 EvtchnSendVersion1;
+ XENBUS_EVTCHN_TRIGGER EvtchnTrigger;
+ XENBUS_EVTCHN_WAIT_V5 EvtchnWaitVersion5;
+ XENBUS_EVTCHN_GET_PORT EvtchnGetPort;
+ XENBUS_EVTCHN_CLOSE EvtchnClose;
+};
+
+/*! \struct _XENBUS_EVTCHN_INTERFACE_V6
+ \brief EVTCHN interface version 6
+ \ingroup interfaces
+*/
+struct _XENBUS_EVTCHN_INTERFACE_V6 {
+ INTERFACE Interface;
+ XENBUS_EVTCHN_ACQUIRE EvtchnAcquire;
+ XENBUS_EVTCHN_RELEASE EvtchnRelease;
+ XENBUS_EVTCHN_OPEN EvtchnOpen;
+ XENBUS_EVTCHN_BIND EvtchnBind;
+ XENBUS_EVTCHN_UNMASK_V4 EvtchnUnmaskVersion4;
+ XENBUS_EVTCHN_SEND EvtchnSend;
+ XENBUS_EVTCHN_TRIGGER EvtchnTrigger;
+ XENBUS_EVTCHN_WAIT_V5 EvtchnWaitVersion5;
+ XENBUS_EVTCHN_GET_PORT EvtchnGetPort;
+ XENBUS_EVTCHN_CLOSE EvtchnClose;
+};
+
+/*! \struct _XENBUS_EVTCHN_INTERFACE_V7
+ \brief EVTCHN interface version 7
+ \ingroup interfaces
+*/
+struct _XENBUS_EVTCHN_INTERFACE_V7 {
+ INTERFACE Interface;
+ XENBUS_EVTCHN_ACQUIRE EvtchnAcquire;
+ XENBUS_EVTCHN_RELEASE EvtchnRelease;
+ XENBUS_EVTCHN_OPEN EvtchnOpen;
+ XENBUS_EVTCHN_BIND EvtchnBind;
+ XENBUS_EVTCHN_UNMASK_V4 EvtchnUnmaskVersion4;
+ XENBUS_EVTCHN_SEND EvtchnSend;
+ XENBUS_EVTCHN_TRIGGER EvtchnTrigger;
+ XENBUS_EVTCHN_GET_COUNT EvtchnGetCount;
+ XENBUS_EVTCHN_WAIT EvtchnWait;
+ XENBUS_EVTCHN_GET_PORT EvtchnGetPort;
+ XENBUS_EVTCHN_CLOSE EvtchnClose;
+};
+
+/*! \struct _XENBUS_EVTCHN_INTERFACE_V8
+ \brief EVTCHN interface version 8
+ \ingroup interfaces
+*/
+struct _XENBUS_EVTCHN_INTERFACE_V8 {
+ INTERFACE Interface;
+ XENBUS_EVTCHN_ACQUIRE EvtchnAcquire;
+ XENBUS_EVTCHN_RELEASE EvtchnRelease;
+ XENBUS_EVTCHN_OPEN EvtchnOpen;
+ XENBUS_EVTCHN_BIND EvtchnBind;
+ XENBUS_EVTCHN_UNMASK EvtchnUnmask;
+ XENBUS_EVTCHN_SEND EvtchnSend;
+ XENBUS_EVTCHN_TRIGGER EvtchnTrigger;
+ XENBUS_EVTCHN_GET_COUNT EvtchnGetCount;
+ XENBUS_EVTCHN_WAIT EvtchnWait;
+ XENBUS_EVTCHN_GET_PORT EvtchnGetPort;
+ XENBUS_EVTCHN_CLOSE EvtchnClose;
+};
+
+typedef struct _XENBUS_EVTCHN_INTERFACE_V8 XENBUS_EVTCHN_INTERFACE,
*PXENBUS_EVTCHN_INTERFACE;
+
+/*! \def XENBUS_EVTCHN
+ \brief Macro at assist in method invocation
+*/
+#define XENBUS_EVTCHN(_Method, _Interface, ...) \
+ (_Interface)->Evtchn ## _Method((PINTERFACE)(_Interface), __VA_ARGS__)
+
+#endif // _WINDLL
+
+#define XENBUS_EVTCHN_INTERFACE_VERSION_MIN 4
+#define XENBUS_EVTCHN_INTERFACE_VERSION_MAX 8
+
+#endif // _XENBUS_EVTCHN_INTERFACE_H
+
diff --git a/include/gnttab_interface.h b/include/gnttab_interface.h
new file mode 100755
index 0000000..61272ab
--- /dev/null
+++ b/include/gnttab_interface.h
@@ -0,0 +1,287 @@
+/* Copyright (c) Citrix Systems Inc.
+ * 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.
+ */
+
+/*! \file gnttab_interface.h
+ \brief XENBUS GNTTAB Interface
+
+ This interface provides access to the hypervisor grant table
+*/
+
+#ifndef _XENBUS_GNTTAB_INTERFACE_H
+#define _XENBUS_GNTTAB_INTERFACE_H
+
+#include <cache_interface.h>
+
+#ifndef _WINDLL
+
+/*! \typedef XENBUS_GNTTAB_ENTRY
+ \brief Grant table entry handle
+*/
+typedef struct _XENBUS_GNTTAB_ENTRY XENBUS_GNTTAB_ENTRY, *PXENBUS_GNTTAB_ENTRY;
+
+/*! \typedef XENBUS_GNTTAB_CACHE
+ \brief Grant table cache handle
+*/
+typedef struct _XENBUS_GNTTAB_CACHE XENBUS_GNTTAB_CACHE, *PXENBUS_GNTTAB_CACHE;
+
+/*! \typedef XENBUS_GNTTAB_ACQUIRE
+ \brief Acquire a reference to the GNTTAB interface
+
+ \param Interface The interface header
+*/
+typedef NTSTATUS
+(*XENBUS_GNTTAB_ACQUIRE)(
+ IN PINTERFACE Interface
+ );
+
+/*! \typedef XENBUS_GNTTAB_RELEASE
+ \brief Release a reference to the GNTTAB interface
+
+ \param Interface The interface header
+*/
+typedef VOID
+(*XENBUS_GNTTAB_RELEASE)(
+ IN PINTERFACE Interface
+ );
+
+/*! \typedef XENBUS_GNTTAB_CREATE_CACHE
+ \brief Create a cache of grant table entries
+
+ \param Interface The interface header
+ \param Name A name for the cache which will be used in debug output
+ \param Reservation The target minimum population of the cache
+ \param AcquireLock A callback invoked to acquire a spinlock
+ \param ReleaseLock A callback invoked to release the spinlock
+ \param Argument An optional context argument passed to the callbacks
+ \param Cache A pointer to a grant table cache handle to be initialized
+*/
+typedef NTSTATUS
+(*XENBUS_GNTTAB_CREATE_CACHE)(
+ IN PINTERFACE Interface,
+ IN const CHAR *Name,
+ IN ULONG Reservation,
+ IN XENBUS_CACHE_ACQUIRE_LOCK AcquireLock,
+ IN XENBUS_CACHE_RELEASE_LOCK ReleaseLock,
+ IN PVOID Argument OPTIONAL,
+ OUT PXENBUS_GNTTAB_CACHE *Cache
+ );
+
+/*! \typedef XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS
+ \brief Get a table entry from the \a Cache permitting access to a given \a
Pfn
+
+ \param Interface The interface header
+ \param Cache The grant table cache handle
+ \param Locked If mutually exclusive access to the cache is already
+ guaranteed then set this to TRUE
+ \param Domain The domid of the domain being granted access
+ \param Pfn The frame number of the page that we are granting access to
+ \param ReadOnly Set to TRUE if the foreign domain is only being granted
+ read access
+ \param Entry A pointer to a grant table entry handle to be initialized
+*/
+typedef NTSTATUS
+(*XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_GNTTAB_CACHE Cache,
+ IN BOOLEAN Locked,
+ IN USHORT Domain,
+ IN PFN_NUMBER Pfn,
+ IN BOOLEAN ReadOnly,
+ OUT PXENBUS_GNTTAB_ENTRY *Entry
+ );
+
+/*! \typedef XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS
+ \brief Revoke foreign access and return the \a Entry to the \a Cache
+
+ \param Interface The interface header
+ \param Cache The grant table cache handle
+ \param Locked If mutually exclusive access to the cache is already
+ guaranteed then set this to TRUE
+ \param Entry The grant table entry handle
+*/
+typedef NTSTATUS
+(*XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_GNTTAB_CACHE Cache,
+ IN BOOLEAN Locked,
+ IN PXENBUS_GNTTAB_ENTRY Entry
+ );
+
+/*! \typedef XENBUS_GNTTAB_GET_REFERENCE
+ \brief Get the reference number of the entry
+
+ \param Interface The interface header
+ \param Entry The grant table entry handle
+ \return The reference number
+*/
+typedef ULONG
+(*XENBUS_GNTTAB_GET_REFERENCE)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_GNTTAB_ENTRY Entry
+ );
+
+/*! \typedef XENBUS_GNTTAB_QUERY_REFERENCE
+ \brief Get the reference number of the entry
+
+ \param Interface The interface header
+ \param Reference The reference number
+ \param Pfn An optional pointer to receive the value of the reference frame
number
+ \param ReadOnly An optional pointer to receive the boolean value of the
read-only flag
+*/
+typedef NTSTATUS
+(*XENBUS_GNTTAB_QUERY_REFERENCE)(
+ IN PINTERFACE Interface,
+ IN ULONG Reference,
+ OUT PPFN_NUMBER Pfn OPTIONAL,
+ OUT PBOOLEAN ReadOnly OPTIONAL
+ );
+
+#define XENBUS_GNTTAB_CONSOLE_REFERENCE 0
+#define XENBUS_GNTTAB_STORE_REFERENCE 1
+
+
+/*! \typedef XENBUS_GNTTAB_DESTROY_CACHE
+ \brief Destroy a cache of grant table entries
+
+ \param Interface The interface header
+ \param Cache The grant table cache handle
+
+ All grant table entries must have been revoked prior to destruction
+ of the cache
+*/
+typedef VOID
+(*XENBUS_GNTTAB_DESTROY_CACHE)(
+ IN PINTERFACE Interface,
+ IN PXENBUS_GNTTAB_CACHE Cache
+ );
+
+/*! \typedef XENBUS_GNTTAB_MAP_FOREIGN_PAGES
+ \brief Map foreign memory pages into the system address space
+
+ \param Interface The interface header
+ \param Domain The domid of the foreign domain that granted the pages
+ \param NumberPages Number of pages to map
+ \param References Array of grant reference numbers shared by the foreign
domain
+ \param ReadOnly If TRUE, pages are mapped with read-only access
+ \param Address The physical address that the foreign pages are mapped under
+*/
+
+typedef NTSTATUS
+(*XENBUS_GNTTAB_MAP_FOREIGN_PAGES)(
+ IN PINTERFACE Interface,
+ IN USHORT Domain,
+ IN ULONG NumberPages,
+ IN PULONG References,
+ IN BOOLEAN ReadOnly,
+ OUT PHYSICAL_ADDRESS *Address
+ );
+
+/*! \typedef XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES
+ \brief Unmap foreign memory pages from the system address space
+
+ \param Interface The interface header
+ \param Address The physical address that the foreign pages are mapped under
+*/
+typedef NTSTATUS
+(*XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES)(
+ IN PINTERFACE Interface,
+ IN PHYSICAL_ADDRESS Address
+ );
+
+// {763679C5-E5C2-4A6D-8B88-6BB02EC42D8E}
+DEFINE_GUID(GUID_XENBUS_GNTTAB_INTERFACE,
+0x763679c5, 0xe5c2, 0x4a6d, 0x8b, 0x88, 0x6b, 0xb0, 0x2e, 0xc4, 0x2d, 0x8e);
+
+/*! \struct _XENBUS_GNTTAB_INTERFACE_V1
+ \brief GNTTAB interface version 1
+ \ingroup interfaces
+*/
+struct _XENBUS_GNTTAB_INTERFACE_V1 {
+ INTERFACE Interface;
+ XENBUS_GNTTAB_ACQUIRE GnttabAcquire;
+ XENBUS_GNTTAB_RELEASE GnttabRelease;
+ XENBUS_GNTTAB_CREATE_CACHE GnttabCreateCache;
+ XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS GnttabPermitForeignAccess;
+ XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS GnttabRevokeForeignAccess;
+ XENBUS_GNTTAB_GET_REFERENCE GnttabGetReference;
+ XENBUS_GNTTAB_DESTROY_CACHE GnttabDestroyCache;
+};
+
+/*! \struct _XENBUS_GNTTAB_INTERFACE_V2
+ \brief GNTTAB interface version 2
+ \ingroup interfaces
+*/
+struct _XENBUS_GNTTAB_INTERFACE_V2 {
+ INTERFACE Interface;
+ XENBUS_GNTTAB_ACQUIRE GnttabAcquire;
+ XENBUS_GNTTAB_RELEASE GnttabRelease;
+ XENBUS_GNTTAB_CREATE_CACHE GnttabCreateCache;
+ XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS GnttabPermitForeignAccess;
+ XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS GnttabRevokeForeignAccess;
+ XENBUS_GNTTAB_GET_REFERENCE GnttabGetReference;
+ XENBUS_GNTTAB_DESTROY_CACHE GnttabDestroyCache;
+ XENBUS_GNTTAB_MAP_FOREIGN_PAGES GnttabMapForeignPages;
+ XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES GnttabUnmapForeignPages;
+};
+
+/*! \struct _XENBUS_GNTTAB_INTERFACE_V3
+ \brief GNTTAB interface version 3
+ \ingroup interfaces
+*/
+struct _XENBUS_GNTTAB_INTERFACE_V3 {
+ INTERFACE Interface;
+ XENBUS_GNTTAB_ACQUIRE GnttabAcquire;
+ XENBUS_GNTTAB_RELEASE GnttabRelease;
+ XENBUS_GNTTAB_CREATE_CACHE GnttabCreateCache;
+ XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS GnttabPermitForeignAccess;
+ XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS GnttabRevokeForeignAccess;
+ XENBUS_GNTTAB_GET_REFERENCE GnttabGetReference;
+ XENBUS_GNTTAB_QUERY_REFERENCE GnttabQueryReference;
+ XENBUS_GNTTAB_DESTROY_CACHE GnttabDestroyCache;
+ XENBUS_GNTTAB_MAP_FOREIGN_PAGES GnttabMapForeignPages;
+ XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES GnttabUnmapForeignPages;
+};
+
+typedef struct _XENBUS_GNTTAB_INTERFACE_V3 XENBUS_GNTTAB_INTERFACE,
*PXENBUS_GNTTAB_INTERFACE;
+
+/*! \def XENBUS_GNTTAB
+ \brief Macro at assist in method invocation
+*/
+#define XENBUS_GNTTAB(_Method, _Interface, ...) \
+ (_Interface)->Gnttab ## _Method((PINTERFACE)(_Interface), __VA_ARGS__)
+
+#endif // _WINDLL
+
+#define XENBUS_GNTTAB_INTERFACE_VERSION_MIN 1
+#define XENBUS_GNTTAB_INTERFACE_VERSION_MAX 3
+
+#endif // _XENBUS_GNTTAB_INTERFACE_H
+
diff --git a/src/xencons/fdo.c b/src/xencons/fdo.c
index 5296c7f..ef26869 100644
--- a/src/xencons/fdo.c
+++ b/src/xencons/fdo.c
@@ -100,6 +100,8 @@ struct _XENCONS_FDO {
XENBUS_SUSPEND_INTERFACE SuspendInterface;
XENBUS_STORE_INTERFACE StoreInterface;
XENBUS_CONSOLE_INTERFACE ConsoleInterface;
+ XENBUS_EVTCHN_INTERFACE EvtchnInterface;
+ XENBUS_GNTTAB_INTERFACE GnttabInterface;
PXENBUS_SUSPEND_CALLBACK SuspendCallbackLate;
};
@@ -3140,6 +3142,8 @@ DEFINE_FDO_GET_INTERFACE(Debug, PXENBUS_DEBUG_INTERFACE)
DEFINE_FDO_GET_INTERFACE(Suspend, PXENBUS_SUSPEND_INTERFACE)
DEFINE_FDO_GET_INTERFACE(Store, PXENBUS_STORE_INTERFACE)
DEFINE_FDO_GET_INTERFACE(Console, PXENBUS_CONSOLE_INTERFACE)
+DEFINE_FDO_GET_INTERFACE(Evtchn, PXENBUS_EVTCHN_INTERFACE)
+DEFINE_FDO_GET_INTERFACE(Gnttab, PXENBUS_GNTTAB_INTERFACE)
#pragma warning(push)
#pragma warning(disable:6014) // Leaking memory '&Dx->Link'
@@ -3252,10 +3256,28 @@ FdoCreate(
if (!NT_SUCCESS(status))
goto fail11;
- status = ConsoleCreate(Fdo, &Fdo->Console);
+ status = FDO_QUERY_INTERFACE(Fdo,
+ XENBUS,
+ EVTCHN,
+ (PINTERFACE)&Fdo->EvtchnInterface,
+ sizeof(Fdo->EvtchnInterface),
+ FALSE);
if (!NT_SUCCESS(status))
goto fail12;
+ status = FDO_QUERY_INTERFACE(Fdo,
+ XENBUS,
+ GNTTAB,
+ (PINTERFACE)&Fdo->GnttabInterface,
+ sizeof(Fdo->GnttabInterface),
+ FALSE);
+ if (!NT_SUCCESS(status))
+ goto fail13;
+
+ status = ConsoleCreate(Fdo, &Fdo->Console);
+ if (!NT_SUCCESS(status))
+ goto fail14;
+
FunctionDeviceObject->Flags |= DO_BUFFERED_IO;
Dx->Fdo = Fdo;
@@ -3272,6 +3294,18 @@ FdoCreate(
FunctionDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
+fail14:
+ Error("fail14\n");
+
+ RtlZeroMemory(&Fdo->GnttabInterface,
+ sizeof(XENBUS_GNTTAB_INTERFACE));
+
+fail13:
+ Error("fail13\n");
+
+ RtlZeroMemory(&Fdo->EvtchnInterface,
+ sizeof(XENBUS_EVTCHN_INTERFACE));
+
fail12:
Error("fail12\n");
@@ -3374,6 +3408,12 @@ FdoDestroy(
ConsoleDestroy(Fdo->Console);
Fdo->Console = NULL;
+ RtlZeroMemory(&Fdo->GnttabInterface,
+ sizeof(XENBUS_GNTTAB_INTERFACE));
+
+ RtlZeroMemory(&Fdo->EvtchnInterface,
+ sizeof(XENBUS_EVTCHN_INTERFACE));
+
RtlZeroMemory(&Fdo->ConsoleInterface,
sizeof (XENBUS_CONSOLE_INTERFACE));
diff --git a/src/xencons/fdo.h b/src/xencons/fdo.h
index 189c70f..c61cc55 100644
--- a/src/xencons/fdo.h
+++ b/src/xencons/fdo.h
@@ -37,6 +37,8 @@
#include <suspend_interface.h>
#include <store_interface.h>
#include <console_interface.h>
+#include <evtchn_interface.h>
+#include <gnttab_interface.h>
#include "driver.h"
@@ -100,6 +102,8 @@ DECLARE_FDO_GET_INTERFACE(Debug, PXENBUS_DEBUG_INTERFACE)
DECLARE_FDO_GET_INTERFACE(Suspend, PXENBUS_SUSPEND_INTERFACE)
DECLARE_FDO_GET_INTERFACE(Store, PXENBUS_STORE_INTERFACE)
DECLARE_FDO_GET_INTERFACE(Console, PXENBUS_CONSOLE_INTERFACE)
+DECLARE_FDO_GET_INTERFACE(Evtchn, PXENBUS_EVTCHN_INTERFACE)
+DECLARE_FDO_GET_INTERFACE(Gnttab, PXENBUS_GNTTAB_INTERFACE)
extern NTSTATUS
FdoCreate(
diff --git a/src/xencons/frontend.c b/src/xencons/frontend.c
index 3cb4f07..fa7443d 100755
--- a/src/xencons/frontend.c
+++ b/src/xencons/frontend.c
@@ -40,6 +40,7 @@
#include "driver.h"
#include "frontend.h"
+#include "ring.h"
#include "thread.h"
#include "dbg_print.h"
#include "assert.h"
@@ -62,6 +63,7 @@ struct _XENCONS_FRONTEND {
PCHAR Name;
PCHAR Protocol;
+ PXENCONS_RING Ring;
XENBUS_DEBUG_INTERFACE DebugInterface;
XENBUS_SUSPEND_INTERFACE SuspendInterface;
@@ -664,9 +666,9 @@ FrontendConnect(
if (!NT_SUCCESS(status))
goto fail2;
- //status = RingConnect(Frontend->Ring);
- //if (!NT_SUCCESS(status))
- // goto fail3;
+ status = RingConnect(Frontend->Ring);
+ if (!NT_SUCCESS(status))
+ goto fail3;
Attempt = 0;
do {
@@ -678,9 +680,9 @@ FrontendConnect(
if (!NT_SUCCESS(status))
break;
- //status = RingStoreWrite(Frontend->Ring, Transaction);
- //if (!NT_SUCCESS(status))
- // goto abort;
+ status = RingStoreWrite(Frontend->Ring, Transaction);
+ if (!NT_SUCCESS(status))
+ goto abort;
status = XENBUS_STORE(TransactionEnd,
&Frontend->StoreInterface,
@@ -691,12 +693,12 @@ FrontendConnect(
continue;
- //abort:
- // (VOID)XENBUS_STORE(TransactionEnd,
- // &Frontend->StoreInterface,
- // Transaction,
- // FALSE);
- // break;
+ abort:
+ (VOID)XENBUS_STORE(TransactionEnd,
+ &Frontend->StoreInterface,
+ Transaction,
+ FALSE);
+ break;
} while (status == STATUS_RETRY);
if (!NT_SUCCESS(status))
@@ -747,8 +749,8 @@ fail5:
fail4:
Error("fail4\n");
-//fail3:
-// Error("fail3\n");
+fail3:
+ Error("fail3\n");
XENBUS_DEBUG(Deregister,
&Frontend->DebugInterface,
@@ -780,7 +782,7 @@ FrontendDisconnect(
__FrontendFree(Frontend->Name);
Frontend->Name = NULL;
- //RingDisconnect(Frontend->Ring);
+ RingDisconnect(Frontend->Ring);
XENBUS_DEBUG(Deregister,
&Frontend->DebugInterface,
@@ -797,13 +799,21 @@ FrontendEnable(
IN PXENCONS_FRONTEND Frontend
)
{
+ NTSTATUS status;
+
Trace("====>\n");
- UNREFERENCED_PARAMETER(Frontend);
- //RingEnable(Frontend->Ring);
+ status = RingEnable(Frontend->Ring);
+ if (!NT_SUCCESS(status))
+ goto fail1;
Trace("<====\n");
return STATUS_SUCCESS;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
}
static VOID
@@ -813,8 +823,7 @@ FrontendDisable(
{
Trace("====>\n");
- UNREFERENCED_PARAMETER(Frontend);
- //RingDisable(Frontend->Ring);
+ RingDisable(Frontend->Ring);
Trace("<====\n");
}
@@ -1204,8 +1213,19 @@ FrontendCreate(
if (!NT_SUCCESS(status))
goto fail4;
+ status = RingCreate(*Frontend, &(*Frontend)->Ring);
+ if (!NT_SUCCESS(status))
+ goto fail5;
+
return STATUS_SUCCESS;
+fail5:
+ Error("fail5\n");
+
+ ThreadAlert((*Frontend)->EjectThread);
+ ThreadJoin((*Frontend)->EjectThread);
+ (*Frontend)->EjectThread = NULL;
+
fail4:
Error("fail4\n");
@@ -1256,6 +1276,9 @@ FrontendDestroy(
ASSERT(Frontend->State == FRONTEND_UNKNOWN);
+ RingDestroy(Frontend->Ring);
+ Frontend->Ring = NULL;
+
ThreadAlert(Frontend->EjectThread);
ThreadJoin(Frontend->EjectThread);
Frontend->EjectThread = NULL;
diff --git a/src/xencons/ring.c b/src/xencons/ring.c
new file mode 100755
index 0000000..321f4e9
--- /dev/null
+++ b/src/xencons/ring.c
@@ -0,0 +1,578 @@
+/* Copyright (c) Citrix Systems Inc.
+* 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 <ntddk.h>
+#include <ntstrsafe.h>
+#include <stdlib.h>
+#include <xen.h>
+
+#include <debug_interface.h>
+#include <store_interface.h>
+#include <evtchn_interface.h>
+#include <gnttab_interface.h>
+
+#include "frontend.h"
+#include "ring.h"
+#include "dbg_print.h"
+#include "assert.h"
+#include "util.h"
+
+struct _XENCONS_RING {
+ PXENCONS_FRONTEND Frontend;
+ KSPIN_LOCK Lock;
+ PMDL Mdl;
+ struct xencons_interface *Shared;
+ PXENBUS_GNTTAB_ENTRY Entry;
+ BOOLEAN Connected;
+ BOOLEAN Enabled;
+ KDPC Dpc;
+ ULONG Dpcs;
+ PXENBUS_EVTCHN_CHANNEL Channel;
+ ULONG Events;
+ XENBUS_STORE_INTERFACE StoreInterface;
+ XENBUS_GNTTAB_INTERFACE GnttabInterface;
+ XENBUS_EVTCHN_INTERFACE EvtchnInterface;
+ XENBUS_DEBUG_INTERFACE DebugInterface;
+ PXENBUS_DEBUG_CALLBACK DebugCallback;
+ PXENBUS_GNTTAB_CACHE GnttabCache;
+};
+
+#define RING_TAG 'GNIR'
+#define MAXNAMELEN 128
+
+static FORCEINLINE PVOID
+__RingAllocate(
+ IN ULONG Length
+ )
+{
+ return __AllocatePoolWithTag(NonPagedPool, Length, RING_TAG);
+}
+
+static FORCEINLINE VOID
+__RingFree(
+ IN PVOID Buffer
+ )
+{
+ __FreePoolWithTag(Buffer, RING_TAG);
+}
+
+__drv_requiresIRQL(DISPATCH_LEVEL)
+RingAcquireLock(
+ IN PXENCONS_RING Ring
+ )
+{
+ ASSERT3U(KeGetCurrentIrql(), == , DISPATCH_LEVEL);
+
+ KeAcquireSpinLockAtDpcLevel(&Ring->Lock);
+}
+
+__drv_requiresIRQL(DISPATCH_LEVEL)
+RingReleaseLock(
+ IN PXENCONS_RING Ring
+ )
+{
+ ASSERT3U(KeGetCurrentIrql(), == , DISPATCH_LEVEL);
+
+ KeReleaseSpinLockFromDpcLevel(&Ring->Lock);
+}
+
+static BOOLEAN
+RingPoll(
+ IN PXENCONS_RING Ring
+ )
+{
+ UNREFERENCED_PARAMETER(Ring);
+ return FALSE;
+}
+
+__drv_functionClass(KDEFERRED_ROUTINE)
+__drv_maxIRQL(DISPATCH_LEVEL)
+__drv_minIRQL(DISPATCH_LEVEL)
+__drv_requiresIRQL(DISPATCH_LEVEL)
+__drv_sameIRQL
+static VOID
+RingDpc(
+ IN PKDPC Dpc,
+ IN PVOID Context,
+ IN PVOID Argument1,
+ IN PVOID Argument2
+ )
+{
+ PXENCONS_RING Ring = Context;
+
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(Argument1);
+ UNREFERENCED_PARAMETER(Argument2);
+
+ ASSERT(Ring != NULL);
+
+ for (;;) {
+ if (!RingPoll(Ring))
+ break;
+ }
+
+ (VOID) XENBUS_EVTCHN(Unmask,
+ &Ring->EvtchnInterface,
+ Ring->Channel,
+ FALSE,
+ FALSE);
+}
+
+KSERVICE_ROUTINE RingEvtchnCallback;
+
+BOOLEAN
+RingEvtchnCallback(
+ IN PKINTERRUPT InterruptObject,
+ IN PVOID Argument
+ )
+{
+ PXENCONS_RING Ring = Argument;
+
+ UNREFERENCED_PARAMETER(InterruptObject);
+
+ ASSERT(Ring != NULL);
+
+ Ring->Events++;
+
+ if (KeInsertQueueDpc(&Ring->Dpc, NULL, NULL))
+ Ring->Dpcs++;
+
+ return TRUE;
+}
+
+static VOID
+RingDebugCallback(
+ IN PVOID Argument,
+ IN BOOLEAN Crashing
+ )
+{
+ PXENCONS_RING Ring = Argument;
+
+ UNREFERENCED_PARAMETER(Crashing);
+
+ XENBUS_DEBUG(Printf,
+ &Ring->DebugInterface,
+ "0x%p [%s]\n",
+ Ring,
+ (Ring->Enabled) ? "ENABLED" : "DISABLED");
+
+ XENBUS_DEBUG(Printf,
+ &Ring->DebugInterface,
+ "Events = %lu, Dpcs = %lu\n",
+ Ring->Events,
+ Ring->Dpcs);
+
+ XENBUS_DEBUG(Printf,
+ &Ring->DebugInterface,
+ "SHARED: in_cons = %u in_prod = %u out_cons = %u out_prod =
%u\n",
+ Ring->Shared->in_cons,
+ Ring->Shared->in_prod,
+ Ring->Shared->out_cons,
+ Ring->Shared->out_prod);
+
+ // Raw Dump of in/out buffers?
+}
+
+NTSTATUS
+RingConnect(
+ IN PXENCONS_RING Ring
+ )
+{
+ CHAR Name[MAXNAMELEN];
+ PFN_NUMBER Pfn;
+ NTSTATUS status;
+
+ Trace("=====>\n");
+
+ status = XENBUS_DEBUG(Acquire, &Ring->DebugInterface);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ status = XENBUS_STORE(Acquire, &Ring->StoreInterface);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = XENBUS_EVTCHN(Acquire, &Ring->EvtchnInterface);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ status = XENBUS_GNTTAB(Acquire, &Ring->GnttabInterface);
+ if (!NT_SUCCESS(status))
+ goto fail4;
+
+ status = RtlStringCbPrintfA(Name,
+ sizeof(Name),
+ "xencons_%s_gnttab",
+ PdoGetName(FrontendGetPdo(Ring->Frontend)));
+ if (!NT_SUCCESS(status))
+ goto fail5;
+
+ status = XENBUS_GNTTAB(CreateCache,
+ &Ring->GnttabInterface,
+ Name,
+ 0,
+ RingAcquireLock,
+ RingReleaseLock,
+ Ring,
+ &Ring->GnttabCache);
+ if (!NT_SUCCESS(status))
+ goto fail6;
+
+ Ring->Mdl = __AllocatePage();
+
+ status = STATUS_NO_MEMORY;
+ if (Ring->Mdl == NULL)
+ goto fail7;
+
+ ASSERT(Ring->Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
+ Ring->Shared = Ring->Mdl->MappedSystemVa;
+ ASSERT(Ring->Shared != NULL);
+
+ Pfn = MmGetMdlPfnArray(Ring->Mdl)[0];
+
+ status = XENBUS_GNTTAB(PermitForeignAccess,
+ &Ring->GnttabInterface,
+ Ring->GnttabCache,
+ TRUE,
+ FrontendGetBackendDomain(Ring->Frontend),
+ Pfn,
+ FALSE,
+ &Ring->Entry);
+ if (!NT_SUCCESS(status))
+ goto fail8;
+
+ Ring->Channel = XENBUS_EVTCHN(Open,
+ &Ring->EvtchnInterface,
+ XENBUS_EVTCHN_TYPE_UNBOUND,
+ RingEvtchnCallback,
+ Ring,
+ FrontendGetBackendDomain(Ring->Frontend),
+ TRUE);
+
+ status = STATUS_UNSUCCESSFUL;
+ if (Ring->Channel == NULL)
+ goto fail9;
+
+ (VOID)XENBUS_EVTCHN(Unmask,
+ &Ring->EvtchnInterface,
+ Ring->Channel,
+ FALSE,
+ TRUE);
+
+ ASSERT(!Ring->Connected);
+ Ring->Connected = TRUE;
+
+ status = XENBUS_DEBUG(Register,
+ &Ring->DebugInterface,
+ __MODULE__ "|RING",
+ RingDebugCallback,
+ Ring,
+ &Ring->DebugCallback);
+ if (!NT_SUCCESS(status))
+ goto fail10;
+
+ Trace("<=====\n");
+ return STATUS_SUCCESS;
+
+fail10:
+ Error("fail10\n");
+
+ Ring->Connected = FALSE;
+
+ XENBUS_EVTCHN(Close,
+ &Ring->EvtchnInterface,
+ Ring->Channel);
+ Ring->Channel = NULL;
+
+fail9:
+ Error("fail9\n");
+
+ (VOID)XENBUS_GNTTAB(RevokeForeignAccess,
+ &Ring->GnttabInterface,
+ Ring->GnttabCache,
+ TRUE,
+ Ring->Entry);
+ Ring->Entry = NULL;
+
+fail8:
+ Error("fail8\n");
+
+ RtlZeroMemory(Ring->Shared, PAGE_SIZE);
+
+ Ring->Shared = NULL;
+ __FreePage(Ring->Mdl);
+ Ring->Mdl = NULL;
+
+
+fail7:
+ Error("fail7\n");
+
+ XENBUS_GNTTAB(DestroyCache,
+ &Ring->GnttabInterface,
+ Ring->GnttabCache);
+ Ring->GnttabCache = NULL;
+
+fail6:
+ Error("fail6\n");
+
+fail5:
+ Error("fail5\n");
+
+ XENBUS_GNTTAB(Release, &Ring->GnttabInterface);
+
+fail4:
+ Error("fail4\n");
+
+ XENBUS_EVTCHN(Release, &Ring->EvtchnInterface);
+
+fail3:
+ Error("fail3\n");
+
+ XENBUS_STORE(Release, &Ring->StoreInterface);
+
+fail2:
+ Error("fail2\n");
+
+ XENBUS_DEBUG(Release, &Ring->DebugInterface);
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+NTSTATUS
+RingStoreWrite(
+ IN PXENCONS_RING Ring,
+ IN PVOID Transaction
+ )
+{
+ ULONG GrantRef;
+ ULONG Port;
+ NTSTATUS status;
+
+ Port = XENBUS_EVTCHN(GetPort,
+ &Ring->EvtchnInterface,
+ Ring->Channel);
+
+ status = XENBUS_STORE(Printf,
+ &Ring->StoreInterface,
+ Transaction,
+ FrontendGetPath(Ring->Frontend),
+ "port",
+ "%u",
+ Port);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ GrantRef = XENBUS_GNTTAB(GetReference,
+ &Ring->GnttabInterface,
+ Ring->Entry);
+
+ status = XENBUS_STORE(Printf,
+ &Ring->StoreInterface,
+ Transaction,
+ FrontendGetPath(Ring->Frontend),
+ "ring-ref",
+ "%u",
+ GrantRef);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ return STATUS_SUCCESS;
+
+fail2:
+ Error("fail2\n");
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+NTSTATUS
+RingEnable(
+ IN PXENCONS_RING Ring
+ )
+{
+ Trace("=====>\n");
+
+ ASSERT3U(KeGetCurrentIrql(), == , DISPATCH_LEVEL);
+
+ KeAcquireSpinLockAtDpcLevel(&Ring->Lock);
+ Ring->Enabled = TRUE;
+ KeReleaseSpinLockFromDpcLevel(&Ring->Lock);
+
+ (VOID)KeInsertQueueDpc(&Ring->Dpc, NULL, NULL);
+
+ Trace("<=====\n");
+ return STATUS_SUCCESS;
+}
+
+VOID
+RingDisable(
+ IN PXENCONS_RING Ring
+ )
+{
+ Trace("=====>\n");
+
+ // empty queue(s)
+
+ ASSERT3U(KeGetCurrentIrql(), == , DISPATCH_LEVEL);
+
+ KeAcquireSpinLockAtDpcLevel(&Ring->Lock);
+ Ring->Enabled = FALSE;
+ KeReleaseSpinLockFromDpcLevel(&Ring->Lock);
+
+ Trace("<=====\n");
+}
+
+VOID
+RingDisconnect(
+ IN PXENCONS_RING Ring
+ )
+{
+ Trace("=====>\n");
+
+ XENBUS_DEBUG(Deregister,
+ &Ring->DebugInterface,
+ Ring->DebugCallback);
+ Ring->DebugCallback = NULL;
+
+ ASSERT(Ring->Connected);
+ Ring->Connected = FALSE;
+
+ ASSERT3U(KeGetCurrentIrql(), == , DISPATCH_LEVEL);
+
+ Ring->Dpcs = 0;
+
+ Ring->Events = 0;
+
+ XENBUS_EVTCHN(Close,
+ &Ring->EvtchnInterface,
+ Ring->Channel);
+ Ring->Channel = NULL;
+
+ (VOID)XENBUS_GNTTAB(RevokeForeignAccess,
+ &Ring->GnttabInterface,
+ Ring->GnttabCache,
+ TRUE,
+ Ring->Entry);
+ Ring->Entry = NULL;
+
+ RtlZeroMemory(Ring->Shared, PAGE_SIZE);
+
+ Ring->Shared = NULL;
+ __FreePage(Ring->Mdl);
+ Ring->Mdl = NULL;
+
+ XENBUS_GNTTAB(DestroyCache,
+ &Ring->GnttabInterface,
+ Ring->GnttabCache);
+ Ring->GnttabCache = NULL;
+
+ XENBUS_GNTTAB(Release, &Ring->GnttabInterface);
+
+ XENBUS_EVTCHN(Release, &Ring->EvtchnInterface);
+
+ XENBUS_STORE(Release, &Ring->StoreInterface);
+
+ XENBUS_DEBUG(Release, &Ring->DebugInterface);
+
+ Trace("<=====\n");
+}
+
+NTSTATUS
+RingCreate(
+ IN PXENCONS_FRONTEND Frontend,
+ OUT PXENCONS_RING *Ring
+ )
+{
+ NTSTATUS status;
+
+ *Ring = __RingAllocate(sizeof(XENCONS_RING));
+
+ status = STATUS_NO_MEMORY;
+ if (*Ring == NULL)
+ goto fail1;
+
+ (*Ring)->Frontend = Frontend;
+
+ FdoGetGnttabInterface(PdoGetFdo(FrontendGetPdo(Frontend)),
+ &(*Ring)->GnttabInterface);
+
+ FdoGetEvtchnInterface(PdoGetFdo(FrontendGetPdo(Frontend)),
+ &(*Ring)->EvtchnInterface);
+
+ FdoGetStoreInterface(PdoGetFdo(FrontendGetPdo(Frontend)),
+ &(*Ring)->StoreInterface);
+
+ FdoGetDebugInterface(PdoGetFdo(FrontendGetPdo(Frontend)),
+ &(*Ring)->DebugInterface);
+
+ KeInitializeSpinLock(&(*Ring)->Lock);
+
+ KeInitializeDpc(&(*Ring)->Dpc, RingDpc, *Ring);
+
+ return STATUS_SUCCESS;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+VOID
+RingDestroy(
+ IN PXENCONS_RING Ring
+ )
+{
+ RtlZeroMemory(&Ring->Dpc, sizeof(KDPC));
+
+ RtlZeroMemory(&Ring->Lock, sizeof(KSPIN_LOCK));
+
+ RtlZeroMemory(&Ring->GnttabInterface,
+ sizeof(XENBUS_GNTTAB_INTERFACE));
+
+ RtlZeroMemory(&Ring->EvtchnInterface,
+ sizeof(XENBUS_EVTCHN_INTERFACE));
+
+ RtlZeroMemory(&Ring->StoreInterface,
+ sizeof(XENBUS_STORE_INTERFACE));
+
+ RtlZeroMemory(&Ring->DebugInterface,
+ sizeof(XENBUS_DEBUG_INTERFACE));
+
+ Ring->Frontend = NULL;
+
+ ASSERT(IsZeroMemory(Ring, sizeof(XENCONS_RING)));
+ __RingFree(Ring);
+}
diff --git a/src/xencons/ring.h b/src/xencons/ring.h
new file mode 100755
index 0000000..e9f549d
--- /dev/null
+++ b/src/xencons/ring.h
@@ -0,0 +1,78 @@
+/* Copyright (c) Citrix Systems Inc.
+* 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.
+*/
+
+#ifndef _XENCONS_RING_H
+#define _XENCONS_RING_H
+
+#include <ntddk.h>
+
+typedef struct _XENCONS_RING XENCONS_RING, *PXENCONS_RING;
+
+#include "frontend.h"
+
+extern NTSTATUS
+RingCreate(
+ IN PXENCONS_FRONTEND Frontend,
+ OUT PXENCONS_RING *Ring
+ );
+
+extern VOID
+RingDestroy(
+ IN PXENCONS_RING Ring
+ );
+
+extern NTSTATUS
+RingConnect(
+ IN PXENCONS_RING Ring
+ );
+
+extern NTSTATUS
+RingStoreWrite(
+ IN PXENCONS_RING Ring,
+ IN PVOID Transaction
+ );
+
+extern NTSTATUS
+RingEnable(
+ IN PXENCONS_RING Ring
+ );
+
+extern VOID
+RingDisable(
+ IN PXENCONS_RING Ring
+ );
+
+extern VOID
+RingDisconnect(
+ IN PXENCONS_RING Ring
+ );
+
+#endif // _XENCONS_RING_H
diff --git a/vs2015/xencons/xencons.vcxproj b/vs2015/xencons/xencons.vcxproj
index 3a1b934..a2fe7d6 100644
--- a/vs2015/xencons/xencons.vcxproj
+++ b/vs2015/xencons/xencons.vcxproj
@@ -68,6 +68,7 @@
<ClCompile Include="../../src/xencons/fdo.c" />
<ClCompile Include="../../src/xencons/pdo.c" />
<ClCompile Include="../../src/xencons/frontend.c" />
+ <ClCompile Include="../../src/xencons/ring.c" />
<ClCompile Include="../../src/xencons/registry.c" />
<ClCompile Include="../../src/xencons/console.c" />
<ClCompile Include="../../src/xencons/stream.c" />
--
2.8.3
_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/win-pv-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |