]> xenbits.xensource.com Git - pvdrivers/win/xenvbd.git/commitdiff
Add XEN:BOOT_EMULATED handler
authorOwen Smith <owen.smith@citrix.com>
Wed, 16 Dec 2020 15:36:10 +0000 (15:36 +0000)
committerPaul Durrant <pdurrant@amazon.com>
Thu, 17 Dec 2020 15:01:51 +0000 (15:01 +0000)
If XEN:BOOT_EMULATED=TRUE is in the system start options, xen.sys will
issue an unplug for only the AUX disks (by writing 0x0004 instead of
0x0001 to port 0x10 during the unplug), this leads to a target being
created for the boot disk which will not be used (due to an emulated
device being present). The non-functioning target will request a reboot
to resolve this, which will return to the current state and request
another reboot.

Signed-off-by: Owen Smith <owen.smith@citrix.com>
src/xenvbd/adapter.c
src/xenvbd/adapter.h
src/xenvbd/target.c

index 721c97ff83c7679d2226edd184150fe72cf1c12e..941587af3494ce38a680929314a7a2f507dc1e8f 100644 (file)
@@ -89,6 +89,7 @@ struct _XENVBD_ADAPTER {
     PXENVBD_THREAD              ScanThread;
     KEVENT                      ScanEvent;
     PXENBUS_STORE_WATCH         ScanWatch;
+    BOOLEAN                     BootEmulated;
 
     ULONG                       BuildIo;
     ULONG                       StartIo;
@@ -412,6 +413,14 @@ AdapterIsTargetEmulated(
     return Emulated;
 }
 
+BOOLEAN
+AdapterBootEmulated(
+    IN  PXENVBD_ADAPTER Adapter
+    )
+{
+    return Adapter->BootEmulated;
+}
+
 static FORCEINLINE VOID
 __AdapterEnumerate(
     IN  PXENVBD_ADAPTER Adapter,
@@ -1179,6 +1188,32 @@ AdapterReleaseLock(
     KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
 }
 
+static FORCEINLINE VOID
+__AdapterSetBootEmulated(
+    IN  PXENVBD_ADAPTER Adapter
+    )
+{
+    CHAR                Key[] = "XEN:BOOT_EMULATED=";
+    PANSI_STRING        Option;
+    PCHAR               Value;
+    NTSTATUS            status;
+
+    Adapter->BootEmulated = FALSE;
+
+    status = RegistryQuerySystemStartOption(Key, &Option);
+    if (!NT_SUCCESS(status))
+        return;
+
+    Value = Option->Buffer + sizeof (Key) - 1;
+
+    if (strcmp(Value, "TRUE") == 0)
+        Adapter->BootEmulated = TRUE;
+    else if (strcmp(Value, "FALSE") != 0)
+        Warning("UNRECOGNIZED VALUE OF %s: %s\n", Key, Value);
+
+    RegistryFreeSzValue(Option);
+}
+
 __drv_requiresIRQL(PASSIVE_LEVEL)
 static NTSTATUS
 __AdapterQueryInterface(
@@ -1356,6 +1391,8 @@ AdapterInitialize(
     if (!NT_SUCCESS(status))
         goto fail10;
 
+    __AdapterSetBootEmulated(Adapter);
+
     status = ThreadCreate(AdapterScanThread,
                           Adapter,
                           &Adapter->ScanThread);
@@ -1377,6 +1414,7 @@ fail12:
     Adapter->ScanThread = NULL;
 fail11:
     Error("fail11\n");
+    Adapter->BootEmulated = FALSE;
     XENBUS_CACHE(Destroy,
                  &Adapter->CacheInterface,
                  Adapter->BounceCache);
@@ -1462,6 +1500,8 @@ AdapterTeardown(
         TargetDestroy(Target);
     }
 
+    Adapter->BootEmulated = FALSE;
+
     XENBUS_CACHE(Destroy,
                  &Adapter->CacheInterface,
                  Adapter->BounceCache);
index 354699ba2bebd71ca3752b1bc66e9c6346b3c089..c6057ff070dde01e901c5431f9e7d14ecd5b7cb2 100644 (file)
@@ -67,6 +67,11 @@ AdapterIsTargetEmulated(
     IN  ULONG           TargetId
     );
 
+extern BOOLEAN
+AdapterBootEmulated(
+    IN  PXENVBD_ADAPTER Adapter
+    );
+
 extern VOID
 AdapterCompleteSrb(
     IN  PXENVBD_ADAPTER Adapter,
index 839860c046b5b48336ccf55fde26335839dc0d30..7935fa0a14a4c80c13835f9b71e037eb197d88e1 100644 (file)
@@ -1377,6 +1377,9 @@ TargetCreate(
     if (TargetId >= XENVBD_MAX_TARGETS)
         return STATUS_RETRY;
 
+    if (TargetId == 0 && AdapterBootEmulated(Adapter))
+        return STATUS_UNSUCCESSFUL;
+
     if (AdapterIsTargetEmulated(Adapter, TargetId))
         return STATUS_RETRY;