[Intel-gfx] bufmgr corruption

Lukas Hejtmanek xhejtman at ics.muni.cz
Fri Mar 6 21:26:38 CET 2009


Hello,

while hunting the bugs, I discovered several things related to the bufmgr.


I830DrmModeInit called from PreInit calls i830_init_bufmgr
However, i830_init_bufmgr is called also from I830ScreenInit.

In result, the i830_init_bufmgr is called twice without being freed in
between.

The function I830CloseScreen calls dri_bufmgr_destroy which frees the bufmgr.
However, *after* this call, calls to i830_uxa_destroy_pixmap are still made
(from FreeResources call of the Xserver) which result in bad things
(segfaults, memory corruption and so on). 

The attached patch puts some armor on libdrm_intel but proper solution is
still needed.

-- 
Lukáš Hejtmánek
-------------- next part --------------
diff --git a/libdrm/intel/intel_bufmgr.c b/libdrm/intel/intel_bufmgr.c
index 25a6828..9a5f4d1 100644
--- a/libdrm/intel/intel_bufmgr.c
+++ b/libdrm/intel/intel_bufmgr.c
@@ -48,41 +48,52 @@ drm_intel_bo *
 drm_intel_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name,
 		   unsigned long size, unsigned int alignment)
 {
-   return bufmgr->bo_alloc(bufmgr, name, size, alignment);
+   if (bufmgr && bufmgr->bo_alloc)
+      return bufmgr->bo_alloc(bufmgr, name, size, alignment);
+   else
+      return NULL;
 }
 
 drm_intel_bo *
 drm_intel_bo_alloc_for_render(drm_intel_bufmgr *bufmgr, const char *name,
 			      unsigned long size, unsigned int alignment)
 {
-   return bufmgr->bo_alloc_for_render(bufmgr, name, size, alignment);
+   if (bufmgr && bufmgr->bo_alloc_for_render)
+      return bufmgr->bo_alloc_for_render(bufmgr, name, size, alignment);
+   else
+      return NULL;
 }
 
 void
 drm_intel_bo_reference(drm_intel_bo *bo)
 {
-   bo->bufmgr->bo_reference(bo);
+   if (bo && bo->bufmgr && bo->bufmgr->bo_reference)
+   	bo->bufmgr->bo_reference(bo);
 }
 
 void
 drm_intel_bo_unreference(drm_intel_bo *bo)
 {
-   if (bo == NULL)
-      return;
-
-   bo->bufmgr->bo_unreference(bo);
+   if (bo && bo->bufmgr && bo->bufmgr->bo_unreference)
+   	bo->bufmgr->bo_unreference(bo);
 }
 
 int
 drm_intel_bo_map(drm_intel_bo *buf, int write_enable)
 {
-   return buf->bufmgr->bo_map(buf, write_enable);
+   if (buf && buf->bufmgr && buf->bufmgr->bo_map)
+      return buf->bufmgr->bo_map(buf, write_enable);
+   else
+      return -ENODEV;
 }
 
 int
 drm_intel_bo_unmap(drm_intel_bo *buf)
 {
-   return buf->bufmgr->bo_unmap(buf);
+   if (buf && buf->bufmgr && buf->bufmgr->bo_unmap)
+      return buf->bufmgr->bo_unmap(buf);
+   else
+      return -ENODEV;
 }
 
 int
@@ -91,7 +102,7 @@ drm_intel_bo_subdata(drm_intel_bo *bo, unsigned long offset,
 {
    int ret;
 
-   if (bo->bufmgr->bo_subdata)
+   if (bo && bo->bufmgr && bo->bufmgr->bo_subdata)
       return bo->bufmgr->bo_subdata(bo, offset, size, data);
    if (size == 0 || data == NULL)
       return 0;
@@ -109,7 +120,7 @@ drm_intel_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
 			 unsigned long size, void *data)
 {
    int ret;
-   if (bo->bufmgr->bo_subdata)
+   if (bo && bo->bufmgr && bo->bufmgr->bo_subdata)
       return bo->bufmgr->bo_get_subdata(bo, offset, size, data);
 
    if (size == 0 || data == NULL)
@@ -126,13 +137,15 @@ drm_intel_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
 void
 drm_intel_bo_wait_rendering(drm_intel_bo *bo)
 {
-   bo->bufmgr->bo_wait_rendering(bo);
+   if (bo && bo->bufmgr && bo->bufmgr->bo_wait_rendering)
+      bo->bufmgr->bo_wait_rendering(bo);
 }
 
 void
 drm_intel_bufmgr_destroy(drm_intel_bufmgr *bufmgr)
 {
-   bufmgr->destroy(bufmgr);
+   if (bufmgr)
+      bufmgr->destroy(bufmgr);
 }
 
 int
@@ -140,25 +153,33 @@ drm_intel_bo_exec(drm_intel_bo *bo, int used,
 		  drm_clip_rect_t *cliprects, int num_cliprects,
 		  int DR4)
 {
-   return bo->bufmgr->bo_exec(bo, used, cliprects, num_cliprects, DR4);
+   if (bo && bo->bufmgr && bo->bufmgr->bo_exec)
+      return bo->bufmgr->bo_exec(bo, used, cliprects, num_cliprects, DR4);
+   else
+      return -ENODEV;
 }
 
 void
 drm_intel_bufmgr_set_debug(drm_intel_bufmgr *bufmgr, int enable_debug)
 {
-   bufmgr->debug = enable_debug;
+   if (bufmgr)
+      bufmgr->debug = enable_debug;
 }
 
 int
 drm_intel_bufmgr_check_aperture_space(drm_intel_bo **bo_array, int count)
 {
-	return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);
+	if (bo_array[0] && bo_array[0]->bufmgr && 
+			   bo_array[0]->bufmgr->check_aperture_space)
+  	    return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);
+	else
+	    return -ENODEV;
 }
 
 int
 drm_intel_bo_flink(drm_intel_bo *bo, uint32_t *name)
 {
-    if (bo->bufmgr->bo_flink)
+    if (bo && bo->bufmgr && bo->bufmgr->bo_flink)
 	return bo->bufmgr->bo_flink(bo, name);
 
     return -ENODEV;
@@ -169,15 +190,18 @@ drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
 			drm_intel_bo *target_bo, uint32_t target_offset,
 			uint32_t read_domains, uint32_t write_domain)
 {
-	return bo->bufmgr->bo_emit_reloc(bo, offset,
+	if (bo && bo->bufmgr && bo->bufmgr->bo_emit_reloc)
+           return bo->bufmgr->bo_emit_reloc(bo, offset,
 					 target_bo, target_offset,
 					 read_domains, write_domain);
+	else
+	   return -ENODEV;
 }
 
 int
 drm_intel_bo_pin(drm_intel_bo *bo, uint32_t alignment)
 {
-    if (bo->bufmgr->bo_pin)
+    if (bo && bo->bufmgr && bo->bufmgr->bo_pin)
 	return bo->bufmgr->bo_pin(bo, alignment);
 
     return -ENODEV;
@@ -186,7 +210,7 @@ drm_intel_bo_pin(drm_intel_bo *bo, uint32_t alignment)
 int
 drm_intel_bo_unpin(drm_intel_bo *bo)
 {
-    if (bo->bufmgr->bo_unpin)
+    if (bo && bo->bufmgr && bo->bufmgr->bo_unpin)
 	return bo->bufmgr->bo_unpin(bo);
 
     return -ENODEV;
@@ -195,7 +219,7 @@ drm_intel_bo_unpin(drm_intel_bo *bo)
 int drm_intel_bo_set_tiling(drm_intel_bo *bo, uint32_t *tiling_mode,
 			    uint32_t stride)
 {
-    if (bo->bufmgr->bo_set_tiling)
+    if (bo && bo->bufmgr && bo->bufmgr->bo_set_tiling)
 	return bo->bufmgr->bo_set_tiling(bo, tiling_mode, stride);
 
     *tiling_mode = I915_TILING_NONE;
@@ -205,7 +229,7 @@ int drm_intel_bo_set_tiling(drm_intel_bo *bo, uint32_t *tiling_mode,
 int drm_intel_bo_get_tiling(drm_intel_bo *bo, uint32_t *tiling_mode,
 			    uint32_t *swizzle_mode)
 {
-    if (bo->bufmgr->bo_get_tiling)
+    if (bo && bo->bufmgr && bo->bufmgr->bo_get_tiling)
 	return bo->bufmgr->bo_get_tiling(bo, tiling_mode, swizzle_mode);
 
     *tiling_mode = I915_TILING_NONE;


More information about the Intel-gfx mailing list