drm/etnaviv: lock MMU while dumping core
authorLucas Stach <l.stach@pengutronix.de>
Tue, 21 May 2019 12:53:40 +0000 (14:53 +0200)
committerLucas Stach <l.stach@pengutronix.de>
Mon, 27 May 2019 14:08:38 +0000 (16:08 +0200)
The devcoredump needs to operate on a stable state of the MMU while
it is writing the MMU state to the coredump. The missing lock
allowed both the userspace submit, as well as the GPU job finish
paths to mutate the MMU state while a coredump is under way.

Fixes: a8c21a5451d8 (drm/etnaviv: add initial etnaviv DRM driver)
Reported-by: David Jander <david@protonic.nl>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Tested-by: David Jander <david@protonic.nl>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
drivers/gpu/drm/etnaviv/etnaviv_dump.c

index 33854c94cb858f1cf62209e5f1c5e8d5de69e3e1..515515ef24f9adbad310199ca09c4478c1237d71 100644 (file)
@@ -125,6 +125,8 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
                return;
        etnaviv_dump_core = false;
 
+       mutex_lock(&gpu->mmu->lock);
+
        mmu_size = etnaviv_iommu_dump_size(gpu->mmu);
 
        /* We always dump registers, mmu, ring and end marker */
@@ -167,6 +169,7 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
        iter.start = __vmalloc(file_size, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY,
                               PAGE_KERNEL);
        if (!iter.start) {
+               mutex_unlock(&gpu->mmu->lock);
                dev_warn(gpu->dev, "failed to allocate devcoredump file\n");
                return;
        }
@@ -234,6 +237,8 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
                                         obj->base.size);
        }
 
+       mutex_unlock(&gpu->mmu->lock);
+
        etnaviv_core_dump_header(&iter, ETDUMP_BUF_END, iter.data);
 
        dev_coredumpv(gpu->dev, iter.start, iter.data - iter.start, GFP_KERNEL);