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

[PATCH v5] 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 |  51 +++++++++++++---
 include/revision.h           |   3 +-
 src/xenfilt/emulated.c       | 115 ++++++++++++++++++++++++++++-------
 src/xenfilt/emulated.h       |  13 ++--
 src/xenfilt/fdo.c            |   6 +-
 src/xenfilt/pdo.c            |   1 +
 6 files changed, 148 insertions(+), 41 deletions(-)

diff --git a/include/emulated_interface.h b/include/emulated_interface.h
index 86a9e06..7d47707 100644
--- a/include/emulated_interface.h
+++ b/include/emulated_interface.h
@@ -72,7 +72,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
@@ -83,12 +83,33 @@ 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 If the device was force-activated, 
force-deactivated
+           or 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_ PXENBUS_EMULATED_ACTIVATION_STATUS    IsForceActivated
+    );
+
 typedef BOOLEAN
 (*XENFILT_EMULATED_IS_DISK_PRESENT_V1)(
     _In_ PVOID  Context,
@@ -120,11 +141,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
@@ -132,6 +153,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;
@@ -139,7 +172,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
@@ -150,6 +183,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 e9e62e6..a63e550 100644
--- a/include/revision.h
+++ b/include/revision.h
@@ -51,6 +51,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..4205cc5 100644
--- a/src/xenfilt/emulated.c
+++ b/src/xenfilt/emulated.c
@@ -45,9 +45,10 @@
 #define MAXNAMELEN  128
 
 typedef struct _XENFILT_EMULATED_DEVICE_DATA {
-    CHAR    DeviceID[MAXNAMELEN];
-    CHAR    InstanceID[MAXNAMELEN];
-    CHAR    CompatibleID[MAXNAMELEN];
+    CHAR                                DeviceID[MAXNAMELEN];
+    CHAR                                InstanceID[MAXNAMELEN];
+    CHAR                                CompatibleID[MAXNAMELEN];
+    XENBUS_EMULATED_ACTIVATION_STATUS   ForceActivate;
 } XENFILT_EMULATED_DEVICE_DATA, *PXENFILT_EMULATED_DEVICE_DATA;
 
 typedef struct _XENFILT_EMULATED_DISK_DATA {
@@ -222,16 +223,17 @@ fail1:
 
 NTSTATUS
 EmulatedAddObject(
-    _In_ PXENFILT_EMULATED_CONTEXT      Context,
-    _In_ PSTR                           DeviceID,
-    _In_ PSTR                           InstanceID,
-    _In_opt_ PSTR                       CompatibleIDs,
-    _In_ XENFILT_EMULATED_OBJECT_TYPE   Type,
-    _Outptr_ PXENFILT_EMULATED_OBJECT   *EmulatedObject
+    _In_ PXENFILT_EMULATED_CONTEXT          Context,
+    _In_ PSTR                               DeviceID,
+    _In_ PSTR                               InstanceID,
+    _In_opt_ PSTR                           CompatibleIDs,
+    _In_ XENFILT_EMULATED_OBJECT_TYPE       Type,
+    _In_ XENBUS_EMULATED_ACTIVATION_STATUS  ForceActivate,
+    _Outptr_ PXENFILT_EMULATED_OBJECT       *EmulatedObject
     )
 {
-    KIRQL                               Irql;
-    NTSTATUS                            status;
+    KIRQL                                   Irql;
+    NTSTATUS                                status;
 
     Trace("====>\n");
 
@@ -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);
@@ -302,36 +306,66 @@ EmulatedRemoveObject(
     __EmulatedFree(EmulatedObject);
 }
 
+static inline BOOLEAN
+EmulatedDeviceMatchesDeviceID(
+    _In_ PXENFILT_EMULATED_DEVICE_DATA  Device,
+    _In_opt_ PSTR                       DeviceID
+    )
+{
+    // EmulatedIsDevicePresent: DeviceID == NULL matches the force-activated 
device
+    if (DeviceID)
+        return _stricmp(DeviceID, Device->DeviceID) == 0;
+    else
+        return Device->ForceActivate == XENBUS_EMULATED_FORCE_ACTIVATED;
+}
+
+static inline BOOLEAN
+EmulatedDeviceMatchesInstanceID(
+    _In_ PXENFILT_EMULATED_DEVICE_DATA  Device,
+    _In_opt_ PSTR                       InstanceID
+    )
+{
+    // EmulatedIsDevicePresent: InstanceID == NULL matches any device instance
+    return InstanceID == NULL || _stricmp(InstanceID, Device->InstanceID) == 0;
+}
+
 static BOOLEAN
 EmulatedIsDevicePresent(
-    _In_ PINTERFACE             Interface,
-    _In_ PSTR                   DeviceID,
-    _In_opt_ PSTR               InstanceID
+    _In_ PINTERFACE                                 Interface,
+    _In_opt_ PSTR                                   DeviceID,
+    _In_opt_ PSTR                                   InstanceID,
+    _Out_opt_ PXENBUS_EMULATED_ACTIVATION_STATUS    IsForceActivated
     )
 {
-    PXENFILT_EMULATED_CONTEXT   Context = Interface->Context;
-    KIRQL                       Irql;
-    PLIST_ENTRY                 ListEntry;
+    PXENFILT_EMULATED_CONTEXT                       Context = 
Interface->Context;
+    KIRQL                                           Irql;
+    PLIST_ENTRY                                     ListEntry;
 
     Trace("====> (%s %s)\n",
-          DeviceID,
+          (DeviceID != NULL) ? DeviceID : "ACTIVE",
           (InstanceID != NULL) ? InstanceID : "ANY");
 
+    if (IsForceActivated)
+        *IsForceActivated = XENBUS_EMULATED_ACTIVATE_NEUTRAL;
+
     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 &&
-            (InstanceID == NULL ||
-             _stricmp(InstanceID, EmulatedObject->Data.Device.InstanceID) == 
0)) {
+            EmulatedDeviceMatchesDeviceID(Device, DeviceID) &&
+            EmulatedDeviceMatchesInstanceID(Device, InstanceID)) {
             Trace("FOUND\n");
+            if (IsForceActivated)
+                *IsForceActivated = Device->ForceActivate;
             break;
         }
 
@@ -345,6 +379,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 +498,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 +506,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 +593,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..c60020f 100644
--- a/src/xenfilt/emulated.h
+++ b/src/xenfilt/emulated.h
@@ -67,12 +67,13 @@ EmulatedTeardown(
 
 extern NTSTATUS
 EmulatedAddObject(
-    _In_ PXENFILT_EMULATED_CONTEXT      Context,
-    _In_ PSTR                           DeviceID,
-    _In_ PSTR                           InstanceID,
-    _In_opt_ PSTR                       CompatibleIDs,
-    _In_ XENFILT_EMULATED_OBJECT_TYPE   Type,
-    _Outptr_ PXENFILT_EMULATED_OBJECT   *EmulatedObject
+    _In_ PXENFILT_EMULATED_CONTEXT          Context,
+    _In_ PSTR                               DeviceID,
+    _In_ PSTR                               InstanceID,
+    _In_opt_ PSTR                           CompatibleIDs,
+    _In_ XENFILT_EMULATED_OBJECT_TYPE       Type,
+    _In_ XENBUS_EMULATED_ACTIVATION_STATUS  ForceActivate,
+    _Outptr_ PXENFILT_EMULATED_OBJECT       *EmulatedObject
     );
 
 extern VOID
diff --git a/src/xenfilt/fdo.c b/src/xenfilt/fdo.c
index 87302bb..ad57c95 100644
--- a/src/xenfilt/fdo.c
+++ b/src/xenfilt/fdo.c
@@ -478,13 +478,15 @@ FdoEnumerate(
     for (Index = 0; Index < Count; Index++) {
 #pragma warning(suppress:6385)  // Reading invalid data from 
'PhysicalDeviceObject'
         if (PhysicalDeviceObject[Index] != NULL) {
-            XENBUS_EMULATED_ACTIVATION_STATUS   ForceActivate =
-                                                
XENBUS_EMULATED_ACTIVATE_NEUTRAL;
+            XENBUS_EMULATED_ACTIVATION_STATUS   ForceActivate;
 
             if (Precedence > 0)
                 ForceActivate = Index == ActiveIndex ?
                                 XENBUS_EMULATED_FORCE_ACTIVATED :
                                 XENBUS_EMULATED_FORCE_DEACTIVATED;
+            else
+                ForceActivate = XENBUS_EMULATED_ACTIVATE_NEUTRAL;
+
             (VOID) PdoCreate(Fdo,
                              PhysicalDeviceObject[Index],
                              Fdo->Type,
diff --git a/src/xenfilt/pdo.c b/src/xenfilt/pdo.c
index 58c9ef0..5327230 100644
--- a/src/xenfilt/pdo.c
+++ b/src/xenfilt/pdo.c
@@ -1701,6 +1701,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®.