Loading arch/arm64/configs/vendor/lito_defconfig +1 −0 Original line number Diff line number Diff line Loading @@ -542,6 +542,7 @@ CONFIG_MSM_QMP=y CONFIG_IOMMU_IO_PGTABLE_FAST=y CONFIG_ARM_SMMU=y CONFIG_IOMMU_TLBSYNC_DEBUG=y CONFIG_ARM_SMMU_TESTBUS_DUMP=y CONFIG_QCOM_LAZY_MAPPING=y CONFIG_IOMMU_DEBUG=y CONFIG_IOMMU_DEBUG_TRACKING=y Loading drivers/iommu/arm-smmu.c +33 −44 Original line number Diff line number Diff line Loading @@ -1165,10 +1165,32 @@ static struct qsmmuv500_tbu_device *qsmmuv500_find_tbu( return NULL; } static void arm_smmu_testbus_dump(struct arm_smmu_device *smmu, u16 sid) { if (smmu->model == QCOM_SMMUV500 && IS_ENABLED(CONFIG_ARM_SMMU_TESTBUS_DUMP)) { struct qsmmuv500_archdata *data; struct qsmmuv500_tbu_device *tbu; data = smmu->archdata; tbu = qsmmuv500_find_tbu(smmu, sid); spin_lock(&testbus_lock); if (tbu) arm_smmu_debug_dump_tbu_testbus(tbu->dev, tbu->base, data->tcu_base, tbu_testbus_sel, data->testbus_version); arm_smmu_debug_dump_tcu_testbus(smmu->dev, ARM_SMMU_GR0(smmu), data->tcu_base, tcu_testbus_sel); spin_unlock(&testbus_lock); } } /* Wait for any pending TLB invalidations to complete */ static int __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, void __iomem *sync, void __iomem *status, struct arm_smmu_domain *smmu_domain) void __iomem *sync, void __iomem *status) { unsigned int spin_cnt, delay; u32 sync_inv_ack, tbu_pwr_status, sync_inv_progress; Loading @@ -1192,46 +1214,6 @@ static int __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, dev_err_ratelimited(smmu->dev, "TLB sync timed out -- SMMU may be deadlocked ack 0x%x pwr 0x%x sync and invalidation progress 0x%x\n", sync_inv_ack, tbu_pwr_status, sync_inv_progress); if (smmu->model == QCOM_SMMUV500 && IS_ENABLED(CONFIG_ARM_SMMU_TESTBUS_DUMP)) { struct qsmmuv500_archdata *data; spin_lock(&testbus_lock); data = smmu->archdata; if (smmu_domain) { struct qsmmuv500_tbu_device *tbu; int i, idx; u16 sid = U16_MAX; struct device *dev = smmu->dev; struct iommu_fwspec *fwspec = dev->iommu_fwspec; struct arm_smmu_cfg *cfg = &smmu_domain->cfg; struct arm_smmu_smr *smrs = smmu->smrs; mutex_lock(&smmu->stream_map_mutex); for_each_cfg_sme(fwspec, i, idx) { if (smmu->s2crs[idx].cbndx == cfg->cbndx) { sid = smrs[idx].id; break; } } mutex_unlock(&smmu->stream_map_mutex); tbu = qsmmuv500_find_tbu(smmu, sid); if (tbu) arm_smmu_debug_dump_tbu_testbus(tbu->dev, tbu->base, data->tcu_base, tbu_testbus_sel, data->testbus_version); } arm_smmu_debug_dump_tcu_testbus(smmu->dev, ARM_SMMU_GR0(smmu), data->tcu_base, tcu_testbus_sel); spin_unlock(&testbus_lock); } BUG_ON(IS_ENABLED(CONFIG_IOMMU_TLBSYNC_DEBUG)); return -EINVAL; } Loading @@ -1242,9 +1224,12 @@ static void arm_smmu_tlb_sync_global(struct arm_smmu_device *smmu) spin_lock_irqsave(&smmu->global_sync_lock, flags); if (__arm_smmu_tlb_sync(smmu, base + ARM_SMMU_GR0_sTLBGSYNC, base + ARM_SMMU_GR0_sTLBGSTATUS, NULL)) base + ARM_SMMU_GR0_sTLBGSTATUS)) { dev_err_ratelimited(smmu->dev, "TLB global sync failed!\n"); arm_smmu_testbus_dump(smmu, U16_MAX); BUG_ON(IS_ENABLED(CONFIG_IOMMU_TLBSYNC_DEBUG)); } spin_unlock_irqrestore(&smmu->global_sync_lock, flags); } Loading @@ -1252,16 +1237,20 @@ static void arm_smmu_tlb_sync_context(void *cookie) { struct arm_smmu_domain *smmu_domain = cookie; struct arm_smmu_device *smmu = smmu_domain->smmu; struct iommu_fwspec *fwspec = smmu_domain->dev->iommu_fwspec; void __iomem *base = ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx); unsigned long flags; spin_lock_irqsave(&smmu_domain->sync_lock, flags); if (__arm_smmu_tlb_sync(smmu, base + ARM_SMMU_CB_TLBSYNC, base + ARM_SMMU_CB_TLBSTATUS, smmu_domain)) base + ARM_SMMU_CB_TLBSTATUS)) { dev_err_ratelimited(smmu->dev, "TLB sync on cb%d failed for device %s\n", smmu_domain->cfg.cbndx, dev_name(smmu_domain->dev)); arm_smmu_testbus_dump(smmu, (u16)fwspec->ids[0]); BUG_ON(IS_ENABLED(CONFIG_IOMMU_TLBSYNC_DEBUG)); } spin_unlock_irqrestore(&smmu_domain->sync_lock, flags); } Loading Loading
arch/arm64/configs/vendor/lito_defconfig +1 −0 Original line number Diff line number Diff line Loading @@ -542,6 +542,7 @@ CONFIG_MSM_QMP=y CONFIG_IOMMU_IO_PGTABLE_FAST=y CONFIG_ARM_SMMU=y CONFIG_IOMMU_TLBSYNC_DEBUG=y CONFIG_ARM_SMMU_TESTBUS_DUMP=y CONFIG_QCOM_LAZY_MAPPING=y CONFIG_IOMMU_DEBUG=y CONFIG_IOMMU_DEBUG_TRACKING=y Loading
drivers/iommu/arm-smmu.c +33 −44 Original line number Diff line number Diff line Loading @@ -1165,10 +1165,32 @@ static struct qsmmuv500_tbu_device *qsmmuv500_find_tbu( return NULL; } static void arm_smmu_testbus_dump(struct arm_smmu_device *smmu, u16 sid) { if (smmu->model == QCOM_SMMUV500 && IS_ENABLED(CONFIG_ARM_SMMU_TESTBUS_DUMP)) { struct qsmmuv500_archdata *data; struct qsmmuv500_tbu_device *tbu; data = smmu->archdata; tbu = qsmmuv500_find_tbu(smmu, sid); spin_lock(&testbus_lock); if (tbu) arm_smmu_debug_dump_tbu_testbus(tbu->dev, tbu->base, data->tcu_base, tbu_testbus_sel, data->testbus_version); arm_smmu_debug_dump_tcu_testbus(smmu->dev, ARM_SMMU_GR0(smmu), data->tcu_base, tcu_testbus_sel); spin_unlock(&testbus_lock); } } /* Wait for any pending TLB invalidations to complete */ static int __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, void __iomem *sync, void __iomem *status, struct arm_smmu_domain *smmu_domain) void __iomem *sync, void __iomem *status) { unsigned int spin_cnt, delay; u32 sync_inv_ack, tbu_pwr_status, sync_inv_progress; Loading @@ -1192,46 +1214,6 @@ static int __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, dev_err_ratelimited(smmu->dev, "TLB sync timed out -- SMMU may be deadlocked ack 0x%x pwr 0x%x sync and invalidation progress 0x%x\n", sync_inv_ack, tbu_pwr_status, sync_inv_progress); if (smmu->model == QCOM_SMMUV500 && IS_ENABLED(CONFIG_ARM_SMMU_TESTBUS_DUMP)) { struct qsmmuv500_archdata *data; spin_lock(&testbus_lock); data = smmu->archdata; if (smmu_domain) { struct qsmmuv500_tbu_device *tbu; int i, idx; u16 sid = U16_MAX; struct device *dev = smmu->dev; struct iommu_fwspec *fwspec = dev->iommu_fwspec; struct arm_smmu_cfg *cfg = &smmu_domain->cfg; struct arm_smmu_smr *smrs = smmu->smrs; mutex_lock(&smmu->stream_map_mutex); for_each_cfg_sme(fwspec, i, idx) { if (smmu->s2crs[idx].cbndx == cfg->cbndx) { sid = smrs[idx].id; break; } } mutex_unlock(&smmu->stream_map_mutex); tbu = qsmmuv500_find_tbu(smmu, sid); if (tbu) arm_smmu_debug_dump_tbu_testbus(tbu->dev, tbu->base, data->tcu_base, tbu_testbus_sel, data->testbus_version); } arm_smmu_debug_dump_tcu_testbus(smmu->dev, ARM_SMMU_GR0(smmu), data->tcu_base, tcu_testbus_sel); spin_unlock(&testbus_lock); } BUG_ON(IS_ENABLED(CONFIG_IOMMU_TLBSYNC_DEBUG)); return -EINVAL; } Loading @@ -1242,9 +1224,12 @@ static void arm_smmu_tlb_sync_global(struct arm_smmu_device *smmu) spin_lock_irqsave(&smmu->global_sync_lock, flags); if (__arm_smmu_tlb_sync(smmu, base + ARM_SMMU_GR0_sTLBGSYNC, base + ARM_SMMU_GR0_sTLBGSTATUS, NULL)) base + ARM_SMMU_GR0_sTLBGSTATUS)) { dev_err_ratelimited(smmu->dev, "TLB global sync failed!\n"); arm_smmu_testbus_dump(smmu, U16_MAX); BUG_ON(IS_ENABLED(CONFIG_IOMMU_TLBSYNC_DEBUG)); } spin_unlock_irqrestore(&smmu->global_sync_lock, flags); } Loading @@ -1252,16 +1237,20 @@ static void arm_smmu_tlb_sync_context(void *cookie) { struct arm_smmu_domain *smmu_domain = cookie; struct arm_smmu_device *smmu = smmu_domain->smmu; struct iommu_fwspec *fwspec = smmu_domain->dev->iommu_fwspec; void __iomem *base = ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx); unsigned long flags; spin_lock_irqsave(&smmu_domain->sync_lock, flags); if (__arm_smmu_tlb_sync(smmu, base + ARM_SMMU_CB_TLBSYNC, base + ARM_SMMU_CB_TLBSTATUS, smmu_domain)) base + ARM_SMMU_CB_TLBSTATUS)) { dev_err_ratelimited(smmu->dev, "TLB sync on cb%d failed for device %s\n", smmu_domain->cfg.cbndx, dev_name(smmu_domain->dev)); arm_smmu_testbus_dump(smmu, (u16)fwspec->ids[0]); BUG_ON(IS_ENABLED(CONFIG_IOMMU_TLBSYNC_DEBUG)); } spin_unlock_irqrestore(&smmu_domain->sync_lock, flags); } Loading