]> xenbits.xensource.com Git - pvdrivers/win/xenbus.git/commitdiff
Avoid potential race with FiltersInstall
authorOwen Smith <owen.smith@citrix.com>
Mon, 28 Jun 2021 12:58:38 +0000 (13:58 +0100)
committerPaul Durrant <pdurrant@amazon.com>
Wed, 30 Jun 2021 16:56:06 +0000 (17:56 +0100)
Is certain situations, a race between XENFILT and XENBUS can lead to XENFILT
not being loaded on the root PCI device node. This is due to XENBUS!DriverEntry
removing the registry value just before the PnP manager determines what filters
to load, and fails to load XENFILT on the root PCI node. This leads to XENBUS
being unable to determine the correct ActiveDevice. Without an ActiveDevice,
no Unplugs are issued, and emulated devices are used for boot, leading to a
reboot prompt before XENVBD can be used as the boot device. The race appears to
be reliable once triggered, and a reboot will follow the same sequence. This
appears to be caused by OS upgrades which affect the order the PnP manager
starts different driver stacks.

This contains a reversion to 9d28a9e9b79, which fixed an upgrade issue that
triggered multiple reboot requirements to reload XENFILT correctly.
If an incompatibility is detected, which can be resolved by a reboot to
complete the driver installation, XENFILT is inserted into the UpperFilters so
that XENFILT is loaded on this reboot. This avoids requiring a second reboot so
that XENFILT can load and determine the ActiveDevice.

Signed-off-by: Owen Smith <owen.smith@citrix.com>
src/xenbus/driver.c

index 1b621fa3a92b57a6e251b164e2fdebd934435996..067bb684f243609533686d9bd86396aece0c286b 100644 (file)
@@ -296,6 +296,9 @@ DriverRemoveFunctionDeviceObject(
     RemoveEntryList(&Dx->ListEntry);
     ASSERT3U(Driver.References, !=, 0);
     References = --Driver.References;
+
+    if (References == 1)
+        FiltersUninstall();
 }
 
 //
@@ -859,16 +862,17 @@ DriverEntry(
                       MICRO_VERSION,
                       BUILD_NUMBER);
     if (!NT_SUCCESS(status)) {
-        if (status == STATUS_INCOMPATIBLE_DRIVER_BLOCKED)
+        if (status == STATUS_INCOMPATIBLE_DRIVER_BLOCKED) {
+            // XenBus.sys is not the same version as Xen.sys
+            // Insert XenFilt to avoid a 2nd reboot in upgrade cases, as AddDevice
+            // will not be called to insert XenFilt.
+            FiltersInstall();
             __DriverRequestReboot();
+        }
 
         goto done;
     }
 
-    // Remove the filters from the registry. They will be re-instated by
-    // the first successful AddDevice.
-    FiltersUninstall();
-
     DriverObject->DriverExtension->AddDevice = DriverAddDevice;
 
     for (Index = 0; Index <= IRP_MJ_MAXIMUM_FUNCTION; Index++) {