From: Sean Paul <sean@poorly.run> To: dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Cc: Sean Paul <seanpaul@chromium.org>, Jordan Crouse <jcrouse@codeaurora.org>, Rob Clark <robdclark@gmail.com>, Sean Paul <sean@poorly.run>, linux-arm-msm@vger.kernel.org Subject: [PATCH v2 1/6] drm/msm/a6xx: Avoid freeing gmu resources multiple times Date: Thu, 23 May 2019 13:16:40 -0400 [thread overview] Message-ID: <20190523171653.138678-1-sean@poorly.run> (raw) From: Sean Paul <seanpaul@chromium.org> The driver checks for gmu->mmio as a sign that the device has been initialized, however there are failures in probe below the mmio init. If one of those is hit, mmio will be non-null but freed. In that case, a6xx_gmu_probe will return an error to a6xx_gpu_init which will in turn call a6xx_gmu_remove which checks gmu->mmio and tries to free resources for a second time. This causes a great boom. Fix this by adding an initialized member to gmu which is set on successful probe and cleared on removal. Changes in v2: - None Cc: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Sean Paul <seanpaul@chromium.org> --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 14 +++++++++----- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 38e2cfa9cec7..aa84edb25d91 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -74,7 +74,7 @@ bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu) u32 val; /* This can be called from gpu state code so make sure GMU is valid */ - if (IS_ERR_OR_NULL(gmu->mmio)) + if (!gmu->initialized) return false; val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS); @@ -90,7 +90,7 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu) u32 val; /* This can be called from gpu state code so make sure GMU is valid */ - if (IS_ERR_OR_NULL(gmu->mmio)) + if (!gmu->initialized) return false; val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS); @@ -695,7 +695,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) struct a6xx_gmu *gmu = &a6xx_gpu->gmu; int status, ret; - if (WARN(!gmu->mmio, "The GMU is not set up yet\n")) + if (WARN(!gmu->initialized, "The GMU is not set up yet\n")) return 0; gmu->hung = false; @@ -765,7 +765,7 @@ bool a6xx_gmu_isidle(struct a6xx_gmu *gmu) { u32 reg; - if (!gmu->mmio) + if (!gmu->initialized) return true; reg = gmu_read(gmu, REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS); @@ -1227,7 +1227,7 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) { struct a6xx_gmu *gmu = &a6xx_gpu->gmu; - if (IS_ERR_OR_NULL(gmu->mmio)) + if (!gmu->initialized) return; a6xx_gmu_stop(a6xx_gpu); @@ -1245,6 +1245,8 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) iommu_detach_device(gmu->domain, gmu->dev); iommu_domain_free(gmu->domain); + + gmu->initialized = false; } int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node) @@ -1309,6 +1311,8 @@ int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node) /* Set up the HFI queues */ a6xx_hfi_init(gmu); + gmu->initialized = true; + return 0; err: a6xx_gmu_memory_free(gmu, gmu->hfi); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index bedd8e6a63aa..39a26dd63674 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -75,6 +75,7 @@ struct a6xx_gmu { struct a6xx_hfi_queue queues[2]; + bool initialized; bool hung; }; -- Sean Paul, Software Engineer, Google / Chromium OS
WARNING: multiple messages have this Message-ID (diff)
From: Sean Paul <sean@poorly.run> To: dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Cc: Sean Paul <sean@poorly.run>, Sean Paul <seanpaul@chromium.org>, linux-arm-msm@vger.kernel.org Subject: [PATCH v2 1/6] drm/msm/a6xx: Avoid freeing gmu resources multiple times Date: Thu, 23 May 2019 13:16:40 -0400 [thread overview] Message-ID: <20190523171653.138678-1-sean@poorly.run> (raw) From: Sean Paul <seanpaul@chromium.org> The driver checks for gmu->mmio as a sign that the device has been initialized, however there are failures in probe below the mmio init. If one of those is hit, mmio will be non-null but freed. In that case, a6xx_gmu_probe will return an error to a6xx_gpu_init which will in turn call a6xx_gmu_remove which checks gmu->mmio and tries to free resources for a second time. This causes a great boom. Fix this by adding an initialized member to gmu which is set on successful probe and cleared on removal. Changes in v2: - None Cc: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Sean Paul <seanpaul@chromium.org> --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 14 +++++++++----- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 38e2cfa9cec7..aa84edb25d91 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -74,7 +74,7 @@ bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu) u32 val; /* This can be called from gpu state code so make sure GMU is valid */ - if (IS_ERR_OR_NULL(gmu->mmio)) + if (!gmu->initialized) return false; val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS); @@ -90,7 +90,7 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu) u32 val; /* This can be called from gpu state code so make sure GMU is valid */ - if (IS_ERR_OR_NULL(gmu->mmio)) + if (!gmu->initialized) return false; val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS); @@ -695,7 +695,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) struct a6xx_gmu *gmu = &a6xx_gpu->gmu; int status, ret; - if (WARN(!gmu->mmio, "The GMU is not set up yet\n")) + if (WARN(!gmu->initialized, "The GMU is not set up yet\n")) return 0; gmu->hung = false; @@ -765,7 +765,7 @@ bool a6xx_gmu_isidle(struct a6xx_gmu *gmu) { u32 reg; - if (!gmu->mmio) + if (!gmu->initialized) return true; reg = gmu_read(gmu, REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS); @@ -1227,7 +1227,7 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) { struct a6xx_gmu *gmu = &a6xx_gpu->gmu; - if (IS_ERR_OR_NULL(gmu->mmio)) + if (!gmu->initialized) return; a6xx_gmu_stop(a6xx_gpu); @@ -1245,6 +1245,8 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) iommu_detach_device(gmu->domain, gmu->dev); iommu_domain_free(gmu->domain); + + gmu->initialized = false; } int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node) @@ -1309,6 +1311,8 @@ int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node) /* Set up the HFI queues */ a6xx_hfi_init(gmu); + gmu->initialized = true; + return 0; err: a6xx_gmu_memory_free(gmu, gmu->hfi); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index bedd8e6a63aa..39a26dd63674 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -75,6 +75,7 @@ struct a6xx_gmu { struct a6xx_hfi_queue queues[2]; + bool initialized; bool hung; }; -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
next reply other threads:[~2019-05-23 17:16 UTC|newest] Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-05-23 17:16 Sean Paul [this message] 2019-05-23 17:16 ` [PATCH v2 1/6] drm/msm/a6xx: Avoid freeing gmu resources multiple times Sean Paul 2019-05-23 17:16 ` [PATCH v2 2/6] drm/msm/a6xx: Remove duplicate irq disable from remove Sean Paul 2019-05-23 17:16 ` Sean Paul 2019-05-23 20:47 ` Jordan Crouse 2019-05-23 20:47 ` Jordan Crouse 2019-05-23 17:16 ` [PATCH v2 3/6] drm/msm/a6xx: Check for ERR or NULL before iounmap Sean Paul 2019-05-23 17:16 ` Sean Paul 2019-05-23 20:48 ` Jordan Crouse 2019-05-23 20:48 ` Jordan Crouse 2019-05-23 17:16 ` [PATCH v2 4/6] drm/msm/a6xx: Remove devm calls from gmu driver Sean Paul 2019-05-23 17:16 ` Sean Paul 2019-05-23 20:51 ` Jordan Crouse 2019-05-23 20:51 ` Jordan Crouse 2019-05-23 17:16 ` [PATCH v2 5/6] drm/msm/a6xx: Drop the device reference in gmu Sean Paul 2019-05-23 17:16 ` Sean Paul 2019-05-23 20:52 ` Jordan Crouse 2019-05-23 20:52 ` Jordan Crouse 2019-05-23 17:16 ` [PATCH v2 6/6] drm/msm/a6xx: Rename a6xx_gmu_probe to a6xx_gmu_init Sean Paul 2019-05-23 17:16 ` Sean Paul 2019-05-23 20:53 ` Jordan Crouse 2019-05-23 20:53 ` Jordan Crouse 2019-05-23 20:46 ` [PATCH v2 1/6] drm/msm/a6xx: Avoid freeing gmu resources multiple times Jordan Crouse 2019-05-23 20:46 ` Jordan Crouse
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20190523171653.138678-1-sean@poorly.run \ --to=sean@poorly.run \ --cc=dri-devel@lists.freedesktop.org \ --cc=freedreno@lists.freedesktop.org \ --cc=jcrouse@codeaurora.org \ --cc=linux-arm-msm@vger.kernel.org \ --cc=robdclark@gmail.com \ --cc=seanpaul@chromium.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.