[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[XENBUS PATCH v2 3/7] Add EMULATED v3



Allow querying the current active device's forced-activation status by
calling EmulatedIsDevicePresent with DeviceID=NULL.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
---
 include/emulated_interface.h | 52 ++++++++++++++++++++++++------
 include/revision.h           |  3 +-
 src/xenfilt/emulated.c       | 62 ++++++++++++++++++++++++++++++++----
 src/xenfilt/emulated.h       |  1 +
 src/xenfilt/pdo.c            |  1 +
 5 files changed, 102 insertions(+), 17 deletions(-)

diff --git a/include/emulated_interface.h b/include/emulated_interface.h
index ead9c14..1f446a9 100644
--- a/include/emulated_interface.h
+++ b/include/emulated_interface.h
@@ -62,7 +62,7 @@ typedef VOID
     _In_ PINTERFACE Interface
     );
 
-/*! \typedef XENFILT_EMULATED_IS_DEVICE_PRESENT
+/*! \typedef XENFILT_EMULATED_IS_DEVICE_PRESENT_V1
     \brief Determine whether a given device is present in the VM
 
     \param Interface The interface header
@@ -73,12 +73,34 @@ typedef VOID
     FALSE if it is not
 */
 typedef BOOLEAN
-(*XENFILT_EMULATED_IS_DEVICE_PRESENT)(
+(*XENFILT_EMULATED_IS_DEVICE_PRESENT_V1)(
     _In_ PVOID      Context,
     _In_ PSTR       DeviceID,
     _In_opt_ PSTR   InstanceID
     );
 
+/*! \typedef XENFILT_EMULATED_IS_DEVICE_PRESENT
+    \brief Determine whether a given device is present in the VM
+
+    \param Interface The interface header
+    \param DeviceID The DeviceID of the device, or NULL to query the force-
+           activated device
+    \param InstanceID The (un-prefixed) InstanceID of the device or
+           NULL to match any device instance
+    \param IsForceActivated Returns 1 if the device was force-activated, -1 if
+           the device was not active and another device was force-activated,
+           and 0 otherwise
+    \return TRUE if the specified device is present in the system or
+            FALSE if it is not
+*/
+typedef BOOLEAN
+(*XENFILT_EMULATED_IS_DEVICE_PRESENT)(
+    _In_ PVOID      Context,
+    _In_opt_ PSTR   DeviceID,
+    _In_opt_ PSTR   InstanceID,
+    _Out_opt_ PLONG IsForceActivated
+    );
+
 typedef BOOLEAN
 (*XENFILT_EMULATED_IS_DISK_PRESENT_V1)(
     _In_ PVOID  Context,
@@ -110,11 +132,11 @@ DEFINE_GUID(GUID_XENFILT_EMULATED_INTERFACE,
     \ingroup interfaces
 */
 struct _XENFILT_EMULATED_INTERFACE_V1 {
-    INTERFACE                           Interface;
-    XENFILT_EMULATED_ACQUIRE            EmulatedAcquire;
-    XENFILT_EMULATED_RELEASE            EmulatedRelease;
-    XENFILT_EMULATED_IS_DEVICE_PRESENT  EmulatedIsDevicePresent;
-    XENFILT_EMULATED_IS_DISK_PRESENT_V1 EmulatedIsDiskPresentVersion1;
+    INTERFACE                               Interface;
+    XENFILT_EMULATED_ACQUIRE                EmulatedAcquire;
+    XENFILT_EMULATED_RELEASE                EmulatedRelease;
+    XENFILT_EMULATED_IS_DEVICE_PRESENT_V1   EmulatedIsDevicePresentVersion1;
+    XENFILT_EMULATED_IS_DISK_PRESENT_V1     EmulatedIsDiskPresentVersion1;
 };
 
 /*! \struct _XENFILT_EMULATED_INTERFACE_V2
@@ -122,6 +144,18 @@ struct _XENFILT_EMULATED_INTERFACE_V1 {
     \ingroup interfaces
 */
 struct _XENFILT_EMULATED_INTERFACE_V2 {
+    INTERFACE                               Interface;
+    XENFILT_EMULATED_ACQUIRE                EmulatedAcquire;
+    XENFILT_EMULATED_RELEASE                EmulatedRelease;
+    XENFILT_EMULATED_IS_DEVICE_PRESENT_V1   EmulatedIsDevicePresentVersion1;
+    XENFILT_EMULATED_IS_DISK_PRESENT        EmulatedIsDiskPresent;
+};
+
+/*! \struct _XENFILT_EMULATED_INTERFACE_V3
+    \brief EMULATED interface version 3
+    \ingroup interfaces
+*/
+struct _XENFILT_EMULATED_INTERFACE_V3 {
     INTERFACE                           Interface;
     XENFILT_EMULATED_ACQUIRE            EmulatedAcquire;
     XENFILT_EMULATED_RELEASE            EmulatedRelease;
@@ -129,7 +163,7 @@ struct _XENFILT_EMULATED_INTERFACE_V2 {
     XENFILT_EMULATED_IS_DISK_PRESENT    EmulatedIsDiskPresent;
 };
 
-typedef struct _XENFILT_EMULATED_INTERFACE_V2 XENFILT_EMULATED_INTERFACE, 
*PXENFILT_EMULATED_INTERFACE;
+typedef struct _XENFILT_EMULATED_INTERFACE_V3 XENFILT_EMULATED_INTERFACE, 
*PXENFILT_EMULATED_INTERFACE;
 
 /*! \def XENFILT_EMULATED
     \brief Macro at assist in method invocation
@@ -140,6 +174,6 @@ typedef struct _XENFILT_EMULATED_INTERFACE_V2 
XENFILT_EMULATED_INTERFACE, *PXENF
 #endif  // _WINDLL
 
 #define XENFILT_EMULATED_INTERFACE_VERSION_MIN  1
-#define XENFILT_EMULATED_INTERFACE_VERSION_MAX  2
+#define XENFILT_EMULATED_INTERFACE_VERSION_MAX  3
 
 #endif  // _XENFILT_EMULATED_INTERFACE_H
diff --git a/include/revision.h b/include/revision.h
index 4c5607a..ec35aeb 100644
--- a/include/revision.h
+++ b/include/revision.h
@@ -59,6 +59,7 @@
     DEFINE_REVISION(0x09000008,  1,  3,  9,  1,  2,  1,  2,  4,  1,  1,  2), \
     DEFINE_REVISION(0x09000009,  1,  4,  9,  1,  2,  1,  2,  4,  1,  1,  2), \
     DEFINE_REVISION(0x0900000A,  1,  4,  9,  1,  2,  1,  2,  4,  2,  1,  2), \
-    DEFINE_REVISION(0x0900000B,  1,  4,  9,  1,  2,  1,  2,  4,  3,  1,  2)
+    DEFINE_REVISION(0x0900000B,  1,  4,  9,  1,  2,  1,  2,  4,  3,  1,  2), \
+    DEFINE_REVISION(0x0900000C,  1,  4,  9,  1,  2,  1,  2,  4,  3,  1,  3)
 
 #endif  // _REVISION_H
diff --git a/src/xenfilt/emulated.c b/src/xenfilt/emulated.c
index 9065364..7a76a87 100644
--- a/src/xenfilt/emulated.c
+++ b/src/xenfilt/emulated.c
@@ -48,6 +48,7 @@ typedef struct _XENFILT_EMULATED_DEVICE_DATA {
     CHAR    DeviceID[MAXNAMELEN];
     CHAR    InstanceID[MAXNAMELEN];
     CHAR    CompatibleID[MAXNAMELEN];
+    LONG    ForceActivate;
 } XENFILT_EMULATED_DEVICE_DATA, *PXENFILT_EMULATED_DEVICE_DATA;
 
 typedef struct _XENFILT_EMULATED_DISK_DATA {
@@ -227,6 +228,7 @@ EmulatedAddObject(
     _In_ PSTR                           InstanceID,
     _In_opt_ PSTR                       CompatibleIDs,
     _In_ XENFILT_EMULATED_OBJECT_TYPE   Type,
+    _In_ LONG                           ForceActivate,
     _Outptr_ PXENFILT_EMULATED_OBJECT   *EmulatedObject
     )
 {
@@ -267,6 +269,8 @@ EmulatedAddObject(
         goto fail2;
 
     (*EmulatedObject)->Type = Type;
+    if (Type == XENFILT_EMULATED_OBJECT_TYPE_PCI)
+        (*EmulatedObject)->Data.Device.ForceActivate = ForceActivate;
 
     KeAcquireSpinLock(&Context->Lock, &Irql);
     InsertTailList(&Context->List, &(*EmulatedObject)->ListEntry);
@@ -305,8 +309,9 @@ EmulatedRemoveObject(
 static BOOLEAN
 EmulatedIsDevicePresent(
     _In_ PINTERFACE             Interface,
-    _In_ PSTR                   DeviceID,
-    _In_opt_ PSTR               InstanceID
+    _In_opt_ PSTR               DeviceID,
+    _In_opt_ PSTR               InstanceID,
+    _Out_opt_ PLONG             IsForceActivated
     )
 {
     PXENFILT_EMULATED_CONTEXT   Context = Interface->Context;
@@ -314,24 +319,32 @@ EmulatedIsDevicePresent(
     PLIST_ENTRY                 ListEntry;
 
     Trace("====> (%s %s)\n",
-          DeviceID,
+          (DeviceID != NULL) ? DeviceID : "ACTIVE",
           (InstanceID != NULL) ? InstanceID : "ANY");
 
+    if (IsForceActivated)
+        *IsForceActivated = 0;
+
     KeAcquireSpinLock(&Context->Lock, &Irql);
 
     ListEntry = Context->List.Flink;
     while (ListEntry != &Context->List) {
-        PXENFILT_EMULATED_OBJECT    EmulatedObject;
+        PXENFILT_EMULATED_OBJECT        EmulatedObject;
+        PXENFILT_EMULATED_DEVICE_DATA   Device;
 
         EmulatedObject = CONTAINING_RECORD(ListEntry,
                                            XENFILT_EMULATED_OBJECT,
                                            ListEntry);
+        Device = &EmulatedObject->Data.Device;
 
         if (EmulatedObject->Type == XENFILT_EMULATED_OBJECT_TYPE_PCI &&
-            _stricmp(DeviceID, EmulatedObject->Data.Device.DeviceID) == 0 &&
+            ((DeviceID == NULL && Device->ForceActivate > 0) ||
+             (DeviceID != NULL && _stricmp(DeviceID, Device->DeviceID) == 0)) 
&&
             (InstanceID == NULL ||
-             _stricmp(InstanceID, EmulatedObject->Data.Device.InstanceID) == 
0)) {
+             _stricmp(InstanceID, Device->InstanceID) == 0)) {
             Trace("FOUND\n");
+            if (IsForceActivated)
+                *IsForceActivated = Device->ForceActivate;
             break;
         }
 
@@ -345,6 +358,16 @@ EmulatedIsDevicePresent(
     return (ListEntry != &Context->List) ? TRUE : FALSE;
 }
 
+static BOOLEAN
+EmulatedIsDevicePresentVersion1(
+    _In_ PINTERFACE             Interface,
+    _In_ PSTR                   DeviceID,
+    _In_opt_ PSTR               InstanceID
+    )
+{
+    return EmulatedIsDevicePresent(Interface, DeviceID, InstanceID, NULL);
+}
+
 static BOOLEAN
 EmulatedIsDiskPresent(
     _In_ PINTERFACE             Interface,
@@ -454,7 +477,7 @@ static struct _XENFILT_EMULATED_INTERFACE_V1 
EmulatedInterfaceVersion1 = {
     { sizeof (struct _XENFILT_EMULATED_INTERFACE_V1), 1, NULL, NULL, NULL },
     EmulatedAcquire,
     EmulatedRelease,
-    EmulatedIsDevicePresent,
+    EmulatedIsDevicePresentVersion1,
     EmulatedIsDiskPresentVersion1
 };
 
@@ -462,6 +485,14 @@ static struct _XENFILT_EMULATED_INTERFACE_V2 
EmulatedInterfaceVersion2 = {
     { sizeof (struct _XENFILT_EMULATED_INTERFACE_V2), 2, NULL, NULL, NULL },
     EmulatedAcquire,
     EmulatedRelease,
+    EmulatedIsDevicePresentVersion1,
+    EmulatedIsDiskPresent
+};
+
+static struct _XENFILT_EMULATED_INTERFACE_V3 EmulatedInterfaceVersion3 = {
+    { sizeof (struct _XENFILT_EMULATED_INTERFACE_V3), 3, NULL, NULL, NULL },
+    EmulatedAcquire,
+    EmulatedRelease,
     EmulatedIsDevicePresent,
     EmulatedIsDiskPresent
 };
@@ -541,6 +572,23 @@ EmulatedGetInterface(
         status = STATUS_SUCCESS;
         break;
     }
+    case 3: {
+        struct _XENFILT_EMULATED_INTERFACE_V3   *EmulatedInterface;
+
+        EmulatedInterface = (struct _XENFILT_EMULATED_INTERFACE_V3 *)Interface;
+
+        status = STATUS_BUFFER_OVERFLOW;
+        if (Size < sizeof (struct _XENFILT_EMULATED_INTERFACE_V3))
+            break;
+
+        *EmulatedInterface = EmulatedInterfaceVersion3;
+
+        ASSERT3U(Interface->Version, ==, Version);
+        Interface->Context = Context;
+
+        status = STATUS_SUCCESS;
+        break;
+    }
     default:
         status = STATUS_NOT_SUPPORTED;
         break;
diff --git a/src/xenfilt/emulated.h b/src/xenfilt/emulated.h
index 9b02268..c01ff6a 100644
--- a/src/xenfilt/emulated.h
+++ b/src/xenfilt/emulated.h
@@ -72,6 +72,7 @@ EmulatedAddObject(
     _In_ PSTR                           InstanceID,
     _In_opt_ PSTR                       CompatibleIDs,
     _In_ XENFILT_EMULATED_OBJECT_TYPE   Type,
+    _In_ LONG                           ForceActivate,
     _Outptr_ PXENFILT_EMULATED_OBJECT   *EmulatedObject
     );
 
diff --git a/src/xenfilt/pdo.c b/src/xenfilt/pdo.c
index 48ae3a3..946c1c5 100644
--- a/src/xenfilt/pdo.c
+++ b/src/xenfilt/pdo.c
@@ -1748,6 +1748,7 @@ PdoCreate(
                                __PdoGetInstanceID(Pdo),
                                CompatibleIDs,
                                __PdoGetType(Pdo),
+                               ForceActivate,
                                &Pdo->EmulatedObject);
     if (!NT_SUCCESS(status))
         goto fail5;
-- 
2.50.1.windows.1



Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.