If we reach the beginning of the LRU AS list, then trigger an error. Signed-off-by: Adrián Larumbe <adrian.larumbe@xxxxxxxxxxxxx> --- drivers/gpu/drm/panfrost/panfrost_job.c | 4 +++- drivers/gpu/drm/panfrost/panfrost_mmu.c | 8 +++++--- drivers/gpu/drm/panfrost/panfrost_mmu.h | 2 +- drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 5 ++++- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c index f640d211cc3a..f0a4690bcdf9 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -213,7 +213,9 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js) return; } - cfg = panfrost_mmu_as_get(pfdev, job->mmu); + ret = panfrost_mmu_as_get(pfdev, job->mmu, &cfg); + if (ret) + return; job_write(pfdev, JS_HEAD_NEXT_LO(js), lower_32_bits(jc_head)); job_write(pfdev, JS_HEAD_NEXT_HI(js), upper_32_bits(jc_head)); diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index 2189e42d2bfa..8514a02d306d 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -155,7 +155,7 @@ static void panfrost_mmu_disable(struct panfrost_device *pfdev, u32 as_nr) write_cmd(pfdev, as_nr, AS_COMMAND_UPDATE); } -u32 panfrost_mmu_as_get(struct panfrost_device *pfdev, struct panfrost_mmu *mmu) +int panfrost_mmu_as_get(struct panfrost_device *pfdev, struct panfrost_mmu *mmu, u32 *asi) { int as; @@ -197,7 +197,8 @@ u32 panfrost_mmu_as_get(struct panfrost_device *pfdev, struct panfrost_mmu *mmu) if (!atomic_read(&lru_mmu->as_count)) break; } - WARN_ON(&lru_mmu->list == &pfdev->as_lru_list); + if (WARN_ON(&lru_mmu->list == &pfdev->as_lru_list)) + return -1; list_del_init(&lru_mmu->list); as = lru_mmu->as; @@ -220,7 +221,8 @@ u32 panfrost_mmu_as_get(struct panfrost_device *pfdev, struct panfrost_mmu *mmu) out: spin_unlock(&pfdev->as_lock); - return as; + *asi = as; + return 0; } void panfrost_mmu_as_put(struct panfrost_device *pfdev, struct panfrost_mmu *mmu) diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.h b/drivers/gpu/drm/panfrost/panfrost_mmu.h index 022a9a74a114..0b2c0b59db3f 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.h +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.h @@ -16,7 +16,7 @@ void panfrost_mmu_fini(struct panfrost_device *pfdev); void panfrost_mmu_reset(struct panfrost_device *pfdev); void panfrost_mmu_suspend_irq(struct panfrost_device *pfdev); -u32 panfrost_mmu_as_get(struct panfrost_device *pfdev, struct panfrost_mmu *mmu); +int panfrost_mmu_as_get(struct panfrost_device *pfdev, struct panfrost_mmu *mmu, u32 *asi); void panfrost_mmu_as_put(struct panfrost_device *pfdev, struct panfrost_mmu *mmu); struct panfrost_mmu *panfrost_mmu_ctx_get(struct panfrost_mmu *mmu); diff --git a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c index f30817bcf8ba..d3436240f847 100644 --- a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c +++ b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c @@ -130,7 +130,10 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, perfcnt->user = user; - as = panfrost_mmu_as_get(pfdev, perfcnt->mapping->mmu); + ret = panfrost_mmu_as_get(pfdev, perfcnt->mapping->mmu, &as); + if (ret) + return -EBUSY; + cfg = GPU_PERFCNT_CFG_AS(as) | GPU_PERFCNT_CFG_MODE(GPU_PERFCNT_CFG_MODE_MANUAL); -- 2.46.2