summaryrefslogtreecommitdiff
path: root/dix
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2015-09-17 16:04:33 -0700
committerAdam Jackson <ajax@redhat.com>2015-09-21 14:18:51 -0400
commit82eb490b0a341729f25d0c42a937fe29d99da521 (patch)
tree5539dd73df5dc00996a5149399bacf2c803abb1b /dix
parent18a93da9b1f429bc54a8b236fcdd38dab58375cd (diff)
privates: Clear screen-specific keys during CloseScreen
The modesetting driver corrupts memory when used after a server regeneration because not enough memory is allocated for its pixmap privates. This happens because its call to dixRegisterScreenSpecificPrivateKey() does nothing because key->initialized is still TRUE from the first server generation. However, the key is not in the screen's linked list of screen-specific privates because that's freed and reallocated during the server generation loop in dix_main(). Fix this by clearing key->initialized before CloseScreen and add a call to dixFreeScreenSpecificPrivates() for GPU screens. v2: Just set key->initialized to FALSE and move dixFreeScreenSpecificPrivates() calls to after CloseScreen. v3: Move dixFreeScreenSpecificPrivates() calls back to just before CloseScreen. Signed-off-by: Aaron Plattner <aplattner@nvidia.com> Reviewed-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'dix')
-rw-r--r--dix/main.c1
-rw-r--r--dix/privates.c9
2 files changed, 10 insertions, 0 deletions
diff --git a/dix/main.c b/dix/main.c
index d7a9cdaae..549567660 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -339,6 +339,7 @@ dix_main(int argc, char *argv[], char *envp[])
for (i = screenInfo.numGPUScreens - 1; i >= 0; i--) {
ScreenPtr pScreen = screenInfo.gpuscreens[i];
FreeScratchPixmapsForScreen(pScreen);
+ dixFreeScreenSpecificPrivates(pScreen);
(*pScreen->CloseScreen) (pScreen);
dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
free(pScreen);
diff --git a/dix/privates.c b/dix/privates.c
index e03b2255b..969d0141c 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -642,6 +642,15 @@ dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key,
void
dixFreeScreenSpecificPrivates(ScreenPtr pScreen)
{
+ DevPrivateType t;
+
+ for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) {
+ DevPrivateKey key;
+
+ for (key = pScreen->screenSpecificPrivates[t].key; key; key = key->next) {
+ key->initialized = FALSE;
+ }
+ }
}
/* Initialize screen-specific privates in AddScreen */