[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 |