summaryrefslogtreecommitdiffstats
path: root/src/gallium/winsys
diff options
context:
space:
mode:
authorBen Skeggs <[email protected]>2015-11-26 14:34:43 +1000
committerBen Skeggs <[email protected]>2015-12-22 13:24:05 +1000
commit323d4da372298900ce02293a682ba563ac29f4cb (patch)
treeb1c88e2101f095fdff42e86c28d066313b297283 /src/gallium/winsys
parent6c1bfff66ca6dd9dac11507889ee17987bed31cb (diff)
nouveau: fix screen creation failure paths
The winsys layer would attempt to cleanup the nouveau_device if screen init failed, however, in most paths the pipe driver would have already destroyed it, resulting in accesses to freed memory etc. This commit fixes the problem by allowing the winsys to detect whether the pipe driver's destroy function needs to be called or not. Signed-off-by: Ben Skeggs <[email protected]> Reviewed-by: Emil Velikov <[email protected]> Reviewed-by: Samuel Pitoiset <[email protected]> Tested-by: Samuel Pitoiset <[email protected]>
Diffstat (limited to 'src/gallium/winsys')
-rw-r--r--src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
index e117dfcd009..456530d7427 100644
--- a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
@@ -59,7 +59,7 @@ nouveau_drm_screen_create(int fd)
{
struct nouveau_device *dev = NULL;
struct nouveau_screen *(*init)(struct nouveau_device *);
- struct nouveau_screen *screen;
+ struct nouveau_screen *screen = NULL;
int ret, dupfd = -1;
pipe_mutex_lock(nouveau_screen_mutex);
@@ -117,7 +117,7 @@ nouveau_drm_screen_create(int fd)
}
screen = init(dev);
- if (!screen)
+ if (!screen || !screen->base.context_create)
goto err;
/* Use dupfd in hash table, to avoid errors if the original fd gets
@@ -130,10 +130,14 @@ nouveau_drm_screen_create(int fd)
return &screen->base;
err:
- if (dev)
- nouveau_device_del(&dev);
- else if (dupfd >= 0)
- close(dupfd);
+ if (screen) {
+ screen->base.destroy(&screen->base);
+ } else {
+ if (dev)
+ nouveau_device_del(&dev);
+ else if (dupfd >= 0)
+ close(dupfd);
+ }
pipe_mutex_unlock(nouveau_screen_mutex);
return NULL;
}