OSDN Git Service

minigbm: Make sure no mappings remain when closing a GEM handle
[android-x86/external-minigbm.git] / drv.c
diff --git a/drv.c b/drv.c
index a9ede86..10a6348 100644 (file)
--- a/drv.c
+++ b/drv.c
@@ -211,7 +211,8 @@ struct combination *drv_get_combination(struct driver *drv, uint32_t format, uin
        return best;
 }
 
-struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint32_t format)
+struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint32_t format,
+                     uint64_t flags)
 {
 
        struct bo *bo;
@@ -224,6 +225,7 @@ struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint3
        bo->width = width;
        bo->height = height;
        bo->format = format;
+       bo->flags = flags;
        bo->num_planes = drv_num_planes_from_format(format);
 
        if (!bo->num_planes) {
@@ -241,7 +243,7 @@ struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, ui
        size_t plane;
        struct bo *bo;
 
-       bo = drv_bo_new(drv, width, height, format);
+       bo = drv_bo_new(drv, width, height, format, flags);
 
        if (!bo)
                return NULL;
@@ -275,7 +277,7 @@ struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint
                return NULL;
        }
 
-       bo = drv_bo_new(drv, width, height, format);
+       bo = drv_bo_new(drv, width, height, format, BO_USE_NONE);
 
        if (!bo)
                return NULL;
@@ -301,6 +303,7 @@ void drv_bo_destroy(struct bo *bo)
 {
        size_t plane;
        uintptr_t total = 0;
+       size_t map_count = 0;
        struct driver *drv = bo->drv;
 
        pthread_mutex_lock(&drv->driver_lock);
@@ -308,13 +311,24 @@ void drv_bo_destroy(struct bo *bo)
        for (plane = 0; plane < bo->num_planes; plane++)
                drv_decrement_reference_count(drv, bo, plane);
 
-       for (plane = 0; plane < bo->num_planes; plane++)
+       for (plane = 0; plane < bo->num_planes; plane++) {
+               void *ptr;
+
                total += drv_get_reference_count(drv, bo, plane);
+               map_count += !drmHashLookup(bo->drv->map_table, bo->handles[plane].u32, &ptr);
+       }
 
        pthread_mutex_unlock(&drv->driver_lock);
 
-       if (total == 0)
+       if (total == 0) {
+               /*
+                * If we leak a reference to the GEM handle being freed here in the mapping table,
+                * we risk using the mapping table entry later for a completely different BO that
+                * gets the same handle. (See b/38250067.)
+                */
+               assert(!map_count);
                bo->drv->backend->bo_destroy(bo);
+       }
 
        free(bo);
 }
@@ -325,7 +339,7 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data)
        size_t plane;
        struct bo *bo;
 
-       bo = drv_bo_new(drv, data->width, data->height, data->format);
+       bo = drv_bo_new(drv, data->width, data->height, data->format, data->flags);
 
        if (!bo)
                return NULL;