[Spice-devel] [PATCH 3/3] Fix corrupted ram data (e.g., release_ring), and unsynchronized worker, after driver is disabled and re-enabled.

Yonit Halperin yhalperi at redhat.com
Mon Jul 12 06:42:53 PDT 2010


On logoff, in Win7 guest, and on switch user and login into a Winxp guest, the driver is disabled and re-enabled (while the miniport in not reset).
However, before the fix, all the draw objects, e.g., surfaces, were still alive in the worker and the release ring still contained objects, while all the driver's data was initialized. This caused blue screens, and panics in the worker.
---
 display/driver.c |    1 +
 display/qxldd.h  |    1 +
 display/res.c    |   21 +++++++++++++++++++++
 display/res.h    |    2 ++
 4 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/display/driver.c b/display/driver.c
index 7dce00e..4eaedc4 100644
--- a/display/driver.c
+++ b/display/driver.c
@@ -256,6 +256,7 @@ BOOL DrvEnableDriver(ULONG engine_version, ULONG enable_data_size, PDRVENABLEDAT
 VOID DrvDisableDriver(VOID)
 {
     DEBUG_PRINT((NULL, 1, "%s\n", __FUNCTION__));
+    ResetAllDevices();
     ResDestroyGlobals();
     CleanGlobalRes();
 }
diff --git a/display/qxldd.h b/display/qxldd.h
index ffa8b8c..b90aaad 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -168,6 +168,7 @@ typedef struct DevRes {
 
     UINT8 *surfaces_used;
 
+    HANDLE driver;
 #ifdef DBG
     int num_free_pages;
     int num_outputs;
diff --git a/display/res.c b/display/res.c
index c769aeb..4480123 100644
--- a/display/res.c
+++ b/display/res.c
@@ -28,6 +28,8 @@
 #include "surface.h"
 #include "dd.h"
 #include "rop.h"
+#include "devioctl.h"
+#include "ntddvdeo.h"
 
 #if (WINVER < 0x0501)
 #define WAIT_FOR_EVENT(pdev, event, timeout) (pdev)->WaitForEvent(event, timeout)
@@ -397,6 +399,8 @@ static void InitRes(PDev *pdev)
     RtlZeroMemory(pdev->Res.palette_cache, sizeof(pdev->Res.palette_cache));
     RingInit(&pdev->Res.dynamic->palette_lru);
     pdev->Res.num_palettes = 0;
+    
+    pdev->Res.driver = pdev->driver;
 
     ONDBG(pdev->Res.num_outputs = 0);
     ONDBG(pdev->Res.num_path_pages = 0);
@@ -3156,5 +3160,22 @@ void CheckAndSetSSE2()
     }
 }
 
+void ResetAllDevices()
+{
+    UINT32 i;
+    EngAcquireSemaphore(res_sem);
 
+    for (i = 0; i < num_global_res; i++) {
+        if (global_res[i].driver) {
+            DWORD length;
+            if (EngDeviceIoControl(global_res[i].driver, IOCTL_VIDEO_RESET_DEVICE,
+                                   NULL, 0, NULL, 0, &length)) {
+                DEBUG_PRINT((NULL, 0, "%s: reset failed druver 0x%lx\n",
+                            __FUNCTION__, global_res[i].driver));
+                
+            }
+        }
+    }
 
+    EngReleaseSemaphore(res_sem);
+}
diff --git a/display/res.h b/display/res.h
index 3bfb0c7..7a10035 100644
--- a/display/res.h
+++ b/display/res.h
@@ -63,4 +63,6 @@ void ResDestroy(PDev *pdev);
 void ResInitGlobals();
 void ResDestroyGlobals();
 void CheckAndSetSSE2();
+void ResetAllDevices();
+
 #endif
-- 
1.6.6.1



More information about the Spice-devel mailing list