Merge "msm: kgsl: Fix null pointer dereference in deferred_destroy"

This commit is contained in:
qctecmdr 2022-06-08 00:15:56 -07:00 committed by Gerrit - the friendly Code Review server
commit 9d152e5c34

View File

@ -1229,6 +1229,24 @@ static u64 kgsl_iommu_get_ttbr0(struct kgsl_pagetable *pagetable)
return pt->ttbr0;
}
/* Set TTBR0 for the given context with the specific configuration */
static void kgsl_iommu_set_ttbr0(struct kgsl_iommu_context *context,
struct kgsl_mmu *mmu, const struct io_pgtable_cfg *pgtbl_cfg)
{
struct adreno_smmu_priv *adreno_smmu;
/* Quietly return if the context doesn't have a domain */
if (!context->domain)
return;
adreno_smmu = dev_get_drvdata(&context->pdev->dev);
/* Enable CX and clocks before we call into SMMU to setup registers */
kgsl_iommu_enable_clk(mmu);
adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, pgtbl_cfg);
kgsl_iommu_disable_clk(mmu);
}
/* FIXME: This is broken for LPAC. For now return the default context bank */
static int kgsl_iommu_get_context_bank(struct kgsl_pagetable *pt)
{
@ -1241,9 +1259,6 @@ static int kgsl_iommu_get_context_bank(struct kgsl_pagetable *pt)
static void kgsl_iommu_destroy_default_pagetable(struct kgsl_pagetable *pagetable)
{
struct kgsl_device *device = KGSL_MMU_DEVICE(pagetable->mmu);
struct kgsl_iommu *iommu = to_kgsl_iommu(pagetable);
struct kgsl_iommu_context *context = &iommu->user_context;
struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(&context->pdev->dev);
struct kgsl_iommu_pt *pt = to_iommu_pt(pagetable);
struct kgsl_global_memdesc *md;
@ -1254,8 +1269,6 @@ static void kgsl_iommu_destroy_default_pagetable(struct kgsl_pagetable *pagetabl
kgsl_iommu_default_unmap(pagetable, &md->memdesc);
}
adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, NULL);
kfree(pt);
}
@ -1325,25 +1338,6 @@ static int kgsl_iopgtbl_alloc(struct kgsl_iommu_context *ctx, struct kgsl_iommu_
return 0;
}
/* Enable TTBR0 for the given context with the specific configuration */
static void kgsl_iommu_enable_ttbr0(struct kgsl_iommu_context *context,
struct kgsl_iommu_pt *pt)
{
struct adreno_smmu_priv *adreno_smmu;
struct kgsl_mmu *mmu = pt->base.mmu;
/* Quietly return if the context doesn't have a domain */
if (!context->domain)
return;
adreno_smmu = dev_get_drvdata(&context->pdev->dev);
/* Enable CX and clocks before we call into SMMU to setup registers */
kgsl_iommu_enable_clk(mmu);
adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, &pt->info.cfg);
kgsl_iommu_disable_clk(mmu);
}
static struct kgsl_pagetable *kgsl_iommu_default_pagetable(struct kgsl_mmu *mmu)
{
struct kgsl_iommu *iommu = &mmu->iommu;
@ -1529,11 +1523,20 @@ static void kgsl_iommu_close(struct kgsl_mmu *mmu)
/* First put away the default pagetables */
kgsl_mmu_putpagetable(mmu->defaultpagetable);
mmu->defaultpagetable = NULL;
kgsl_mmu_putpagetable(mmu->securepagetable);
/*
* Flush the workqueue to ensure pagetables are
* destroyed before proceeding further
*/
flush_workqueue(kgsl_driver.workqueue);
mmu->defaultpagetable = NULL;
mmu->securepagetable = NULL;
kgsl_iommu_set_ttbr0(&iommu->lpac_context, mmu, NULL);
kgsl_iommu_set_ttbr0(&iommu->user_context, mmu, NULL);
/* Next, detach the context banks */
kgsl_iommu_detach_context(&iommu->user_context);
kgsl_iommu_detach_context(&iommu->lpac_context);
@ -2222,6 +2225,7 @@ static int iommu_probe_user_context(struct kgsl_device *device,
{
struct kgsl_iommu *iommu = KGSL_IOMMU(device);
struct kgsl_mmu *mmu = &device->mmu;
struct kgsl_iommu_pt *pt;
int ret;
ret = kgsl_iommu_setup_context(mmu, node, &iommu->user_context,
@ -2247,14 +2251,14 @@ static int iommu_probe_user_context(struct kgsl_device *device,
if (!test_bit(KGSL_MMU_IOPGTABLE, &mmu->features))
return 0;
pt = to_iommu_pt(mmu->defaultpagetable);
/* Enable TTBR0 on the default and LPAC contexts */
kgsl_iommu_enable_ttbr0(&iommu->user_context,
to_iommu_pt(mmu->defaultpagetable));
kgsl_iommu_set_ttbr0(&iommu->user_context, mmu, &pt->info.cfg);
set_smmu_aperture(device, &iommu->user_context);
kgsl_iommu_enable_ttbr0(&iommu->lpac_context,
to_iommu_pt(mmu->defaultpagetable));
kgsl_iommu_set_ttbr0(&iommu->lpac_context, mmu, &pt->info.cfg);
/* FIXME: set LPAC SMMU aperture */
return 0;