|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH] Tolerate running in a non-Xen VM
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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |