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

[XENBUS PATCH v6 07/11] xenfilt: Add Xenbus device precedence mechanism



Define registry values in xenfilt\Parameters with the names being
compatible IDs and values being numeric precedences.

The Xenbus device with the highest precedence should always be activated
over devices with lower precedence, ignoring Active* values.

If a device is force-activated, get its IDs directly instead of via
Active* values.

Define XENBUS_EMULATED_ACTIVATION_STATUS in emulated_interface.h for
latter use.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
---
 include/emulated_interface.h | 10 +++++
 src/xenfilt/driver.c         | 71 ++++++++++++++++++++++++++++++++++++
 src/xenfilt/driver.h         |  7 ++++
 src/xenfilt/fdo.c            | 28 +++++++++++++-
 src/xenfilt/pdo.c            | 62 +++++++++++++++++--------------
 src/xenfilt/pdo.h            |  7 ++--
 6 files changed, 153 insertions(+), 32 deletions(-)

diff --git a/include/emulated_interface.h b/include/emulated_interface.h
index ead9c14..86a9e06 100644
--- a/include/emulated_interface.h
+++ b/include/emulated_interface.h
@@ -42,6 +42,16 @@
 
 #ifndef _WINDLL
 
+/*! \typedef XENBUS_EMULATED_ACTIVATION_STATUS
+    \brief If the device was force-activated, force-deactivated or
+           otherwise.
+*/
+typedef enum _XENBUS_EMULATED_ACTIVATION_STATUS {
+    XENBUS_EMULATED_ACTIVATE_NEUTRAL = 0,
+    XENBUS_EMULATED_FORCE_ACTIVATED = 1,
+    XENBUS_EMULATED_FORCE_DEACTIVATED = 2,
+} XENBUS_EMULATED_ACTIVATION_STATUS, *PXENBUS_EMULATED_ACTIVATION_STATUS;
+
 /*! \typedef XENFILT_EMULATED_ACQUIRE
     \brief Acquire a reference to the EMULATED interface
 
diff --git a/src/xenfilt/driver.c b/src/xenfilt/driver.c
index 16e4deb..67287d7 100644
--- a/src/xenfilt/driver.c
+++ b/src/xenfilt/driver.c
@@ -279,6 +279,77 @@ DriverGetActive(
     return __DriverGetActive(Key, Value);
 }
 
+_On_failure_(_Post_satisfies_(*Precedence == 0))
+NTSTATUS
+DriverGetPrecedence(
+    _In_ PDEVICE_OBJECT PhysicalDeviceObject,
+    _Out_ PULONG        Precedence
+    )
+{
+    HANDLE              ParametersKey;
+    HANDLE              PrecedenceKey;
+    PSTR                CompatibleIDs;
+    ULONG               Index;
+    NTSTATUS            status;
+
+    status = RegistryOpenParametersKey(KEY_READ, &ParametersKey);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = RegistryOpenSubKey(ParametersKey,
+                                "Precedence",
+                                KEY_READ,
+                                &PrecedenceKey);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = DriverQueryId(PhysicalDeviceObject,
+                           BusQueryCompatibleIDs,
+                           &CompatibleIDs);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    Index = 0;
+
+    do {
+        ULONG   Length = (ULONG)strlen(&CompatibleIDs[Index]);
+
+        if (Length == 0)
+            break;
+
+        status = RegistryQueryDwordValue(PrecedenceKey,
+                                         &CompatibleIDs[Index],
+                                         Precedence);
+        if (NT_SUCCESS(status))
+            goto done;
+
+        Index += Length + 1;
+    } while (1);
+
+    *Precedence = 0;
+
+done:
+    if (*Precedence)
+        Info("%s found precedence %lX\n", CompatibleIDs, *Precedence);
+
+    ExFreePool(CompatibleIDs);
+    RegistryCloseKey(PrecedenceKey);
+    RegistryCloseKey(ParametersKey);
+
+    return STATUS_SUCCESS;
+
+fail3:
+    RegistryCloseKey(PrecedenceKey);
+
+fail2:
+    RegistryCloseKey(ParametersKey);
+
+fail1:
+    *Precedence = 0;
+
+    return status;
+}
+
 static BOOLEAN
 DriverIsActivePresent(
     VOID
diff --git a/src/xenfilt/driver.h b/src/xenfilt/driver.h
index 9c703c1..cf6a2d6 100644
--- a/src/xenfilt/driver.h
+++ b/src/xenfilt/driver.h
@@ -54,6 +54,13 @@ DriverGetActive(
     _Outptr_result_z_ PSTR  *Value
     );
 
+_On_failure_(_Post_satisfies_(*Precedence == 0))
+extern NTSTATUS
+DriverGetPrecedence(
+    _In_ PDEVICE_OBJECT PhysicalDeviceObject,
+    _Out_ PULONG        Precedence
+    );
+
 typedef enum _XENFILT_FILTER_STATE {
     XENFILT_FILTER_ENABLED = 0,
     XENFILT_FILTER_PENDING,
diff --git a/src/xenfilt/fdo.c b/src/xenfilt/fdo.c
index 594da4a..87302bb 100644
--- a/src/xenfilt/fdo.c
+++ b/src/xenfilt/fdo.c
@@ -404,6 +404,8 @@ FdoEnumerate(
     ULONG                   Count;
     PLIST_ENTRY             ListEntry;
     ULONG                   Index;
+    ULONG                   ActiveIndex;
+    ULONG                   Precedence;
     NTSTATUS                status;
 
     Count = Relations->Count;
@@ -458,11 +460,35 @@ FdoEnumerate(
         ListEntry = Next;
     }
 
+    ActiveIndex = Precedence = 0;
+    for (Index = 0; Index < Count; Index++) {
+        ULONG   ThisPrecedence;
+
+        if (PhysicalDeviceObject[Index] != NULL) {
+            status = DriverGetPrecedence(PhysicalDeviceObject[Index],
+                                         &ThisPrecedence);
+            if (ThisPrecedence > Precedence) {
+                ActiveIndex = Index;
+                Precedence = ThisPrecedence;
+            }
+        }
+    }
+
     // Walk the list and create PDO filters for any new devices
     for (Index = 0; Index < Count; Index++) {
 #pragma warning(suppress:6385)  // Reading invalid data from 
'PhysicalDeviceObject'
         if (PhysicalDeviceObject[Index] != NULL) {
-            (VOID) PdoCreate(Fdo, PhysicalDeviceObject[Index], Fdo->Type);
+            XENBUS_EMULATED_ACTIVATION_STATUS   ForceActivate =
+                                                
XENBUS_EMULATED_ACTIVATE_NEUTRAL;
+
+            if (Precedence > 0)
+                ForceActivate = Index == ActiveIndex ?
+                                XENBUS_EMULATED_FORCE_ACTIVATED :
+                                XENBUS_EMULATED_FORCE_DEACTIVATED;
+            (VOID) PdoCreate(Fdo,
+                             PhysicalDeviceObject[Index],
+                             Fdo->Type,
+                             ForceActivate);
             ObDereferenceObject(PhysicalDeviceObject[Index]);
         }
     }
diff --git a/src/xenfilt/pdo.c b/src/xenfilt/pdo.c
index 4f40c4f..58c9ef0 100644
--- a/src/xenfilt/pdo.c
+++ b/src/xenfilt/pdo.c
@@ -249,15 +249,16 @@ __PdoGetFdo(
 
 static NTSTATUS
 PdoSetDeviceInformation(
-    _In_ PXENFILT_PDO   Pdo
+    _In_ PXENFILT_PDO                       Pdo,
+    _In_ XENBUS_EMULATED_ACTIVATION_STATUS  ForceActivate
     )
 {
-    PXENFILT_DX         Dx = Pdo->Dx;
-    PSTR                DeviceID;
-    PSTR                ActiveDeviceID;
-    PSTR                InstanceID;
-    PSTR                LocationInformation;
-    NTSTATUS            status;
+    PXENFILT_DX                             Dx = Pdo->Dx;
+    PSTR                                    DeviceID;
+    PSTR                                    ActiveDeviceID;
+    PSTR                                    InstanceID;
+    PSTR                                    LocationInformation;
+    NTSTATUS                                status;
 
     status = DriverQueryId(Pdo->LowerDeviceObject,
                            BusQueryDeviceID,
@@ -265,19 +266,23 @@ PdoSetDeviceInformation(
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    status = DriverGetActive("DeviceID",
-                             &ActiveDeviceID);
-    if (NT_SUCCESS(status)) {
-        Pdo->Active = (_stricmp(DeviceID, ActiveDeviceID) == 0) ?
-                      TRUE :
-                      FALSE;
-
-        ExFreePool(ActiveDeviceID);
+    if (ForceActivate != XENBUS_EMULATED_ACTIVATE_NEUTRAL) {
+        Pdo->Active = ForceActivate == XENBUS_EMULATED_FORCE_ACTIVATED;
     } else {
-        Pdo->Active = FALSE;
+        status = DriverGetActive("DeviceID",
+                                &ActiveDeviceID);
+        if (NT_SUCCESS(status)) {
+            Pdo->Active = (_stricmp(DeviceID, ActiveDeviceID) == 0) ?
+                        TRUE :
+                        FALSE;
+
+            ExFreePool(ActiveDeviceID);
+        } else {
+            Pdo->Active = FALSE;
+        }
     }
 
-    if (Pdo->Active) {
+    if (Pdo->Active && ForceActivate == XENBUS_EMULATED_ACTIVATE_NEUTRAL) {
         status = DriverGetActive("InstanceID",
                                  &InstanceID);
         if (!NT_SUCCESS(status))
@@ -1620,18 +1625,19 @@ PdoSuspend(
 
 NTSTATUS
 PdoCreate(
-    _In_ PXENFILT_FDO                   Fdo,
-    _In_ PDEVICE_OBJECT                 PhysicalDeviceObject,
-    _In_ XENFILT_EMULATED_OBJECT_TYPE   Type
+    _In_ PXENFILT_FDO                       Fdo,
+    _In_ PDEVICE_OBJECT                     PhysicalDeviceObject,
+    _In_ XENFILT_EMULATED_OBJECT_TYPE       Type,
+    _In_ XENBUS_EMULATED_ACTIVATION_STATUS  ForceActivate
     )
 {
-    PDEVICE_OBJECT                      LowerDeviceObject;
-    ULONG                               DeviceType;
-    PDEVICE_OBJECT                      FilterDeviceObject;
-    PXENFILT_DX                         Dx;
-    PXENFILT_PDO                        Pdo;
-    PSTR                                CompatibleIDs;
-    NTSTATUS                            status;
+    PDEVICE_OBJECT                          LowerDeviceObject;
+    ULONG                                   DeviceType;
+    PDEVICE_OBJECT                          FilterDeviceObject;
+    PXENFILT_DX                             Dx;
+    PXENFILT_PDO                            Pdo;
+    PSTR                                    CompatibleIDs;
+    NTSTATUS                                status;
 
     ASSERT(Type != XENFILT_EMULATED_OBJECT_TYPE_UNKNOWN);
 
@@ -1680,7 +1686,7 @@ PdoCreate(
     Pdo->LowerDeviceObject = LowerDeviceObject;
     Pdo->Type = Type;
 
-    status = PdoSetDeviceInformation(Pdo);
+    status = PdoSetDeviceInformation(Pdo, ForceActivate);
     if (!NT_SUCCESS(status))
         goto fail4;
 
diff --git a/src/xenfilt/pdo.h b/src/xenfilt/pdo.h
index 85bc07f..c0c06a4 100644
--- a/src/xenfilt/pdo.h
+++ b/src/xenfilt/pdo.h
@@ -80,9 +80,10 @@ PdoGetDeviceObject(
 
 extern NTSTATUS
 PdoCreate(
-    _In_ PXENFILT_FDO                   Fdo,
-    _In_ PDEVICE_OBJECT                 PhysicalDeviceObject,
-    _In_ XENFILT_EMULATED_OBJECT_TYPE   Type
+    _In_ PXENFILT_FDO                       Fdo,
+    _In_ PDEVICE_OBJECT                     PhysicalDeviceObject,
+    _In_ XENFILT_EMULATED_OBJECT_TYPE       Type,
+    _In_ XENBUS_EMULATED_ACTIVATION_STATUS  ForceActivate
     );
 
 extern VOID
-- 
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®.