]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/etnaviv: lock MMU while dumping core
authorLucas Stach <l.stach@pengutronix.de>
Tue, 21 May 2019 12:53:40 +0000 (14:53 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 22 Jun 2019 06:15:17 +0000 (08:15 +0200)
[ Upstream commit 1396500d673bd027683a0609ff84dca7eb6ea2e7 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/etnaviv/etnaviv_dump.c

index 9146e30e24a6de20d8bda5f80c7ea7470ddca334..468dff2f79040e32ed972a01481370c317d11b79 100644 (file)
@@ -124,6 +124,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 */
@@ -166,6 +168,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;
        }
@@ -233,6 +236,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);