]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iommu: arm-smmu-qcom: Ensure smmu is powered up in set_ttbr0_cfg
authorAnna Maniscalco <anna.maniscalco2000@gmail.com>
Thu, 7 May 2026 15:43:15 +0000 (17:43 +0200)
committerWill Deacon <will@kernel.org>
Tue, 19 May 2026 11:46:02 +0000 (12:46 +0100)
arm_smmu_write_context_bank() assumes it is being called with RPM
active, but it turns out that is not guaranteed in the path from
qcom_adreno_smmu_set_ttbr0_cfg(), so it's possible for the register
writes to get lost when configuring the context bank while the GPU is
idle, leading to page faults later.
Add the RPM calls here to make sure the SMMU is active before we touch
it.

Signed-off-by: Anna Maniscalco <anna.maniscalco2000@gmail.com>
Reviewed-by: Rob Clark <rob.clark@oss.qualcomm.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c

index 5747b908e49a6ed979c4adcfa2ba456b45334e09..e2c914fccd6fcac770b414de7b9ae3e8532f8711 100644 (file)
@@ -261,6 +261,7 @@ static int qcom_adreno_smmu_set_ttbr0_cfg(const void *cookie,
        struct io_pgtable *pgtable = io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops);
        struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
        struct arm_smmu_cb *cb = &smmu_domain->smmu->cbs[cfg->cbndx];
+       int ret;
 
        /* The domain must have split pagetables already enabled */
        if (cb->tcr[0] & ARM_SMMU_TCR_EPD1)
@@ -290,8 +291,16 @@ static int qcom_adreno_smmu_set_ttbr0_cfg(const void *cookie,
                cb->ttbr[0] |= FIELD_PREP(ARM_SMMU_TTBRn_ASID, cb->cfg->asid);
        }
 
+       ret = pm_runtime_resume_and_get(smmu_domain->smmu->dev);
+       if (ret < 0) {
+               dev_err(smmu_domain->smmu->dev, "failed to get runtime PM: %d\n", ret);
+               return -ENODEV;
+       }
+
        arm_smmu_write_context_bank(smmu_domain->smmu, cb->cfg->cbndx);
 
+       pm_runtime_put_autosuspend(smmu_domain->smmu->dev);
+
        return 0;
 }