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

[win-pv-devel] [PATCH] Tolerate running in a non-Xen VM


  • To: <win-pv-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Paul Durrant <paul.durrant@xxxxxxxxxx>
  • Date: Mon, 16 Sep 2019 13:35:12 +0100
  • Authentication-results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=paul.durrant@xxxxxxxxxx; spf=Pass smtp.mailfrom=Paul.Durrant@xxxxxxxxxx; spf=None smtp.helo=postmaster@xxxxxxxxxxxxxxx
  • Cc: Paul Durrant <paul.durrant@xxxxxxxxxx>
  • Delivery-date: Mon, 16 Sep 2019 12:35:25 +0000
  • Ironport-sdr: nGX46fha5I5RVuJq0PZ/VclQrPo1sCldqCYT/o2fNgnFn1+I9+mKxzaDkwyhWh/c2/oKgebS7F yUMNEIo/OpQtVorZkA5Z0MlOI7CYf7a4iNJCjmDf/QEB6F9SIV4NUXQsjBR09whgw8AJvLEtJt IH4/Ks+ct0psGetAPOpZBRMBHzsf5vEgQNAEX6isuYbQY0Si0mo882x23kS+dy1jRWv9wM9Sca YTLBsw24OFv0bUHU/naAPIN8NFBbpypAy4aeyFKgfbJyioO/hBq0FH3U9o5rKfGp38hkYVkTUG F4Q=
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

If a disk image with XENBUS installed is booted in a non-Xen environment
then this will currently lead to a BSOD. This patch makes things fail
more gracefully by:

a) Making sure an attempt at a hypercall doesn't indirect into an
   uninitialized hypercall page.
b) Making XenTouch() in XEN handle a STATUS_NOT_IMPLEMENTED failure from
   XenVersion(), and have XENBUS and XENFILT use this failure mode to
   quiesce themselved.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xen/driver.c    | 37 ++++++++++++++++++++-----------------
 src/xen/hypercall.c | 26 +++++++++++++-------------
 src/xen/hypercall.h |  4 ++--
 src/xenbus/driver.c |  4 +++-
 4 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/src/xen/driver.c b/src/xen/driver.c
index 74f3d64..fe638d7 100644
--- a/src/xen/driver.c
+++ b/src/xen/driver.c
@@ -113,16 +113,20 @@ XenTouch(
     CHAR            Extra[XEN_EXTRAVERSION_LEN];
     NTSTATUS        status;
 
+    status = STATUS_INCOMPATIBLE_DRIVER_BLOCKED;
     if (MajorVersion != MAJOR_VERSION ||
         MinorVersion != MINOR_VERSION ||
         MicroVersion != MICRO_VERSION ||
         BuildNumber != BUILD_NUMBER)
         goto fail1;
 
-    if (Reference++ != 0)
+    if (Reference != 0)
         goto done;
 
     status = XenVersion(&Major, &Minor);
+    if (status == STATUS_NOT_IMPLEMENTED)
+        goto fail2;
+
     ASSERT(NT_SUCCESS(status));
 
     status = XenVersionExtra(Extra);
@@ -136,12 +140,16 @@ XenTouch(
               __XEN_INTERFACE_VERSION__);
 
 done:
+    Reference++;
+
     return STATUS_SUCCESS;
 
+fail2:
 fail1:
-    Info("MODULE '%s' NOT COMPATIBLE (REBOOT REQUIRED)\n", Name);
+    if (status == STATUS_INCOMPATIBLE_DRIVER_BLOCKED)
+        Info("MODULE '%s' NOT COMPATIBLE (REBOOT REQUIRED)\n", Name);
 
-    return STATUS_INCOMPATIBLE_DRIVER_BLOCKED;
+    return status;
 }
 
 static VOID
@@ -249,25 +257,23 @@ DllInitialize(
     if (!NT_SUCCESS(status))
         goto fail7;
 
-    status = HypercallInitialize();
-    if (!NT_SUCCESS(status))
-        goto fail8;
+    HypercallInitialize();
 
     status = BugCheckInitialize();
     if (!NT_SUCCESS(status))
-        goto fail9;
+        goto fail8;
 
     status = ModuleInitialize();
     if (!NT_SUCCESS(status))
-        goto fail10;
+        goto fail9;
 
     status = ProcessInitialize();
     if (!NT_SUCCESS(status))
-        goto fail11;
+        goto fail10;
 
     status = UnplugInitialize();
     if (!NT_SUCCESS(status))
-        goto fail12;
+        goto fail11;
 
     RegistryCloseKey(ParametersKey);
 
@@ -277,24 +283,21 @@ DllInitialize(
 
     return STATUS_SUCCESS;
 
-fail12:
-    Error("fail12\n");
-
-    ProcessTeardown();
-
 fail11:
     Error("fail11\n");
 
-    ModuleTeardown();
+    ProcessTeardown();
 
 fail10:
     Error("fail10\n");
 
-    BugCheckTeardown();
+    ModuleTeardown();
 
 fail9:
     Error("fail9\n");
 
+    BugCheckTeardown();
+
     HypercallTeardown();
 
 fail8:
diff --git a/src/xen/hypercall.c b/src/xen/hypercall.c
index b63d432..54f3a10 100644
--- a/src/xen/hypercall.c
+++ b/src/xen/hypercall.c
@@ -50,6 +50,7 @@ static ULONG        XenBaseLeaf = 0x40000000;
 
 static PHYSICAL_ADDRESS HypercallPage[MAXIMUM_HYPERCALL_PAGE_COUNT];
 static ULONG            HypercallPageCount;
+static BOOLEAN          HypercallPageInitialized;
 
 typedef UCHAR           HYPERCALL_GATE[32];
 typedef HYPERCALL_GATE  *PHYPERCALL_GATE;
@@ -74,9 +75,11 @@ HypercallPopulate(
 
         __writemsr(HypercallMsr, HypercallPage[Index].QuadPart);
     }
+
+    HypercallPageInitialized = TRUE;
 }
 
-NTSTATUS
+VOID
 HypercallInitialize(
     VOID
     )
@@ -86,9 +89,7 @@ HypercallInitialize(
     ULONG       ECX = 'DEAD';
     ULONG       EDX = 'DEAD';
     ULONG_PTR   Index;
-    NTSTATUS    status;
 
-    status = STATUS_UNSUCCESSFUL;
     for (;;) {
         CHAR    Signature[13] = {0};
 
@@ -103,8 +104,11 @@ HypercallInitialize(
             
         XenBaseLeaf += 0x100;
         
-        if (XenBaseLeaf > 0x40000100)
-            goto fail1;
+        if (XenBaseLeaf > 0x40000100) {
+            LogPrintf(LOG_LEVEL_INFO,
+                      "XEN: BASE CPUID LEAF NOT FOUND\n");
+            return;
+        }
     }
 
     LogPrintf(LOG_LEVEL_INFO,
@@ -128,19 +132,12 @@ HypercallInitialize(
     HypercallMsr = EBX;
 
     HypercallPopulate();
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)", status);
-
-    return status;
 }
 
 extern uintptr_t __stdcall hypercall2(uint32_t ord, uintptr_t arg1, uintptr_t 
arg2);
 extern uintptr_t __stdcall hypercall3(uint32_t ord, uintptr_t arg1, uintptr_t 
arg2, uintptr_t arg3);
 
-ULONG_PTR
+LONG_PTR
 __Hypercall(
     ULONG       Ordinal,
     ULONG       Count,
@@ -150,6 +147,9 @@ __Hypercall(
     va_list     Arguments;
     ULONG_PTR   Value;
 
+    if (!HypercallPageInitialized)
+        return -ENOSYS;
+
     va_start(Arguments, Count);
     switch (Count) {
     case 2: {
diff --git a/src/xen/hypercall.h b/src/xen/hypercall.h
index b201d12..c9e34a9 100644
--- a/src/xen/hypercall.h
+++ b/src/xen/hypercall.h
@@ -39,12 +39,12 @@
 
 #include <public/xen.h>
 
-extern NTSTATUS
+extern VOID
 HypercallInitialize(
     VOID
     );
 
-extern ULONG_PTR
+extern LONG_PTR
 __Hypercall(
     ULONG       Ordinal,
     ULONG       Count,
diff --git a/src/xenbus/driver.c b/src/xenbus/driver.c
index a1c7b56..1b621fa 100644
--- a/src/xenbus/driver.c
+++ b/src/xenbus/driver.c
@@ -859,7 +859,9 @@ DriverEntry(
                       MICRO_VERSION,
                       BUILD_NUMBER);
     if (!NT_SUCCESS(status)) {
-        __DriverRequestReboot();
+        if (status == STATUS_INCOMPATIBLE_DRIVER_BLOCKED)
+            __DriverRequestReboot();
+
         goto done;
     }
 
-- 
2.5.3


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.