]> xenbits.xensource.com Git - pvdrivers/win/xenbus.git/commitdiff
Add emulated NVMe to IsDiskPresent results
authorOwen Smith <owen.smith@citrix.com>
Mon, 28 Jun 2021 12:58:39 +0000 (13:58 +0100)
committerPaul Durrant <pdurrant@amazon.com>
Wed, 30 Jun 2021 16:59:55 +0000 (17:59 +0100)
IsDiskPresent currently only reports the presence of emulated IDE disks. When
using emulated NVMe disks, its possible to start booting off the emulated disk,
but have XenVbd 'take over' resulting in storage requests to the emulated NVMe
disk timing out and failing. This results in a Windows error on boot
"Status 0xc000000e. A required device isnt connected or can't be accessed"

Query the CompatibleIDs and, if present, add the last CompatibleID to emulated
objects of type PCI. When querying if a disk is preset, also check for PCI
devices which match the CompatibleID "PCI\CC_0108". This will prevent XenVbd
enumerating a PV disk which is has a matching emulated NVMe device.

Signed-off-by: Owen Smith <owen.smith@citrix.com>
src/xenfilt/emulated.c
src/xenfilt/emulated.h
src/xenfilt/pdo.c

index 827c9058fe5d6dc6eaf1c2bb6c52634146f41b3a..0c2c0876187519e2569fe13d53c7592252b7655c 100644 (file)
@@ -46,6 +46,7 @@
 typedef struct _XENFILT_EMULATED_DEVICE_DATA {
     CHAR    DeviceID[MAXNAMELEN];
     CHAR    InstanceID[MAXNAMELEN];
+    CHAR    CompatibleID[MAXNAMELEN];
 } XENFILT_EMULATED_DEVICE_DATA, *PXENFILT_EMULATED_DEVICE_DATA;
 
 typedef struct _XENFILT_EMULATED_DISK_DATA {
@@ -92,9 +93,12 @@ EmulatedSetObjectDeviceData(
     IN  PXENFILT_EMULATED_OBJECT        EmulatedObject,
     IN  XENFILT_EMULATED_OBJECT_TYPE    Type,
     IN  PCHAR                           DeviceID,
-    IN  PCHAR                           InstanceID
+    IN  PCHAR                           InstanceID,
+    IN  PCHAR                           CompatibleIDs OPTIONAL
     )
 {
+    ULONG                               Index;
+    PCHAR                               LastMatch;
     NTSTATUS                            status;
 
     status = STATUS_INVALID_PARAMETER;
@@ -113,6 +117,30 @@ EmulatedSetObjectDeviceData(
                                 InstanceID);
     ASSERT(NT_SUCCESS(status));
 
+    if (CompatibleIDs == NULL)
+        goto done;
+
+    Index = 0;
+    LastMatch = CompatibleIDs;
+    for (;;) {
+        ULONG   Length;
+
+        Length = (ULONG)strlen(&CompatibleIDs[Index]);
+        if (Length == 0)
+            break;
+
+        LastMatch = &CompatibleIDs[Index];
+
+        Index += Length + 1;
+    }
+
+    status = RtlStringCbPrintfA(EmulatedObject->Data.Device.CompatibleID,
+                                MAXNAMELEN,
+                                "%s",
+                                LastMatch);
+    ASSERT(NT_SUCCESS(status));
+
+done:
     return STATUS_SUCCESS;
 
 fail1:
@@ -126,7 +154,8 @@ EmulatedSetObjectDiskData(
     IN  PXENFILT_EMULATED_OBJECT        EmulatedObject,
     IN  XENFILT_EMULATED_OBJECT_TYPE    Type,
     IN  PCHAR                           DeviceID,
-    IN  PCHAR                           InstanceID
+    IN  PCHAR                           InstanceID,
+    IN  PCHAR                           CompatibleIDs OPTIONAL
     )
 {
     PCHAR                               End;
@@ -136,6 +165,7 @@ EmulatedSetObjectDiskData(
     NTSTATUS                            status;
 
     UNREFERENCED_PARAMETER(DeviceID);
+    UNREFERENCED_PARAMETER(CompatibleIDs);
 
     status = STATUS_INVALID_PARAMETER;
     if (Type != XENFILT_EMULATED_OBJECT_TYPE_IDE)
@@ -194,6 +224,7 @@ EmulatedAddObject(
     IN  PXENFILT_EMULATED_CONTEXT       Context,
     IN  PCHAR                           DeviceID,
     IN  PCHAR                           InstanceID,
+    IN  PCHAR                           CompatibleIDs OPTIONAL,
     IN  XENFILT_EMULATED_OBJECT_TYPE    Type,
     OUT PXENFILT_EMULATED_OBJECT        *EmulatedObject
     )
@@ -214,14 +245,16 @@ EmulatedAddObject(
         status = EmulatedSetObjectDeviceData(*EmulatedObject,
                                              Type,
                                              DeviceID,
-                                             InstanceID);
+                                             InstanceID,
+                                             CompatibleIDs);
         break;
 
     case XENFILT_EMULATED_OBJECT_TYPE_IDE:
         status = EmulatedSetObjectDiskData(*EmulatedObject,
                                            Type,
                                            DeviceID,
-                                           InstanceID);
+                                           InstanceID,
+                                           CompatibleIDs);
         break;
 
     default:
@@ -339,6 +372,13 @@ EmulatedIsDiskPresent(
             break;
         }
 
+        if (EmulatedObject->Type == XENFILT_EMULATED_OBJECT_TYPE_PCI &&
+            _stricmp("PCI\\CC_0108", EmulatedObject->Data.Device.CompatibleID) == 0 &&
+            Index <= 3) {
+            Trace("FOUND\n");
+            break;
+        }
+
         ListEntry = ListEntry->Flink;
     }
 
index 57edee2585d7f20ec25130fa533c6ed9a0ba96fd..049c0bb55398a206bbec2a1264bfa0c9da1dda61 100644 (file)
@@ -69,6 +69,7 @@ EmulatedAddObject(
     IN  PXENFILT_EMULATED_CONTEXT       Context,
     IN  PCHAR                           DeviceID,
     IN  PCHAR                           InstanceID,
+    IN  PCHAR                           CompatibleIDs OPTIONAL,
     IN  XENFILT_EMULATED_OBJECT_TYPE    Type,
     OUT PXENFILT_EMULATED_OBJECT        *EmulatedObject
     );
index 0f6e6ce74b90f1c734502ce80743f44010437dc7..b3569a39af65dc41635ca7316c1291331535c3b4 100644 (file)
@@ -376,6 +376,14 @@ __PdoGetInstanceID(
            Dx->InstanceID : "";
 }
 
+static FORCEINLINE XENFILT_EMULATED_OBJECT_TYPE
+__PdoGetType(
+    IN  PXENFILT_PDO    Pdo
+    )
+{
+    return Pdo->Type;
+}
+
 static FORCEINLINE PCHAR
 __PdoGetLocationInformation(
     IN  PXENFILT_PDO    Pdo
@@ -2112,6 +2120,7 @@ PdoCreate(
     PDEVICE_OBJECT                  FilterDeviceObject;
     PXENFILT_DX                     Dx;
     PXENFILT_PDO                    Pdo;
+    PCHAR                           CompatibleIDs;
     NTSTATUS                        status;
 
     ASSERT(Type != XENFILT_EMULATED_OBJECT_TYPE_UNKNOWN);
@@ -2173,14 +2182,24 @@ PdoCreate(
     if (!NT_SUCCESS(status))
         goto fail6;
 
+    status = DriverQueryId(Pdo->LowerDeviceObject,
+                           BusQueryCompatibleIDs,
+                           &CompatibleIDs);
+    if (!NT_SUCCESS(status))
+        CompatibleIDs = NULL;
+
     status = EmulatedAddObject(DriverGetEmulatedContext(),
                                __PdoGetDeviceID(Pdo),
                                __PdoGetInstanceID(Pdo),
-                               Pdo->Type,
+                               CompatibleIDs,
+                               __PdoGetType(Pdo),
                                &Pdo->EmulatedObject);
     if (!NT_SUCCESS(status))
         goto fail7;
 
+    if (CompatibleIDs)
+        ExFreePool(CompatibleIDs);
+
     __PdoSetName(Pdo);
 
     Info("%p (%s) %s\n",
@@ -2204,6 +2223,9 @@ PdoCreate(
 fail7:
     Error("fail7\n");
 
+    if (CompatibleIDs)
+        ExFreePool(CompatibleIDs);
+
     PdoClearDeviceInformation(Pdo);
 
 fail6: