From: Jason Gunthorpe jgg@nvidia.com
mainline inclusion from mainline-v6.12-rc1 commit 8c153ef95697242b72646d2c4cf6c4b23ccf35a3 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IB4WDJ CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
These values can be computed from the other values already stored in the config. Move the calculation to arm_smmu_write_strtab() and do it directly before writing the registers.
This moves all the logic to calculate the two registers into one function from three and saves an unimportant 16 bytes from the arm_smmu_device.
Suggested-by: Nicolin Chen nicolinc@nvidia.com Reviewed-by: Nicolin Chen nicolinc@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Link: https://lore.kernel.org/r/4-v4-6416877274e1+1af-smmuv3_tidy_jgg@nvidia.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Kunkun Jiang jiangkunkun@huawei.com --- drivers/iommu/arm/arm-smmu-v3/arm-s-smmu-v3.c | 6 +- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 55 +++++++++---------- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 2 - 3 files changed, 29 insertions(+), 34 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-s-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-s-smmu-v3.c index 29d4c0c71041..7fe90d410ba9 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-s-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-s-smmu-v3.c @@ -770,8 +770,7 @@ void virtcca_smmu_device_init(struct platform_device *pdev, struct arm_smmu_devi params_ptr->is_cmd_queue = 1; params_ptr->smmu_id = smmu->s_smmu_id; params_ptr->ioaddr = smmu->ioaddr; - params_ptr->strtab_base_RA_bit = - (smmu->strtab_cfg.strtab_base >> S_STRTAB_BASE_RA_SHIFT) & 0x1; + params_ptr->strtab_base_RA_bit = 0x1; params_ptr->q_base_RA_WA_bit = (smmu->cmdq.q.q_base >> S_CMDQ_BASE_RA_SHIFT) & 0x1; if (tmi_smmu_device_reset(__pa(params_ptr)) != 0) { @@ -801,8 +800,7 @@ void virtcca_smmu_device_init(struct platform_device *pdev, struct arm_smmu_devi params_ptr->smmu_id = smmu->s_smmu_id; params_ptr->q_base_RA_WA_bit = (smmu->evtq.q.q_base >> S_EVTQ_BASE_WA_SHIFT) & 0x1; - params_ptr->strtab_base_RA_bit = - (smmu->strtab_cfg.strtab_base >> S_STRTAB_BASE_RA_SHIFT) & 0x1; + params_ptr->strtab_base_RA_bit = 0x1; if (tmi_smmu_device_reset(__pa(params_ptr)) != 0) { dev_err(smmu->dev, "S_SMMU: failed to set s event queue regs\n"); smmu->s_smmu_id = ARM_S_SMMU_INVALID_ID; diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index ce9a81caebe5..0953abb8093d 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -4146,7 +4146,6 @@ static int arm_smmu_prepare_init_l2_strtab(struct device *dev, void *data)
static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu) { - u64 reg; u32 l1size; struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; int ret = 0; @@ -4171,13 +4170,6 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu) return -ENOMEM; }
- /* Configure strtab_base_cfg for 2 levels */ - reg = FIELD_PREP(STRTAB_BASE_CFG_FMT, STRTAB_BASE_CFG_FMT_2LVL); - reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, - ilog2(cfg->l2.num_l1_ents) + STRTAB_SPLIT); - reg |= FIELD_PREP(STRTAB_BASE_CFG_SPLIT, STRTAB_SPLIT); - cfg->strtab_base_cfg = reg; - cfg->l2.l2ptrs = devm_kcalloc(smmu->dev, cfg->l2.num_l1_ents, sizeof(*cfg->l2.l2ptrs), GFP_KERNEL); if (!cfg->l2.l2ptrs) @@ -4194,7 +4186,6 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu) { - u64 reg; u32 size; struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
@@ -4210,34 +4201,21 @@ static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu) } cfg->linear.num_ents = 1 << smmu->sid_bits;
- /* Configure strtab_base_cfg for a linear table covering all SIDs */ - reg = FIELD_PREP(STRTAB_BASE_CFG_FMT, STRTAB_BASE_CFG_FMT_LINEAR); - reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, smmu->sid_bits); - cfg->strtab_base_cfg = reg; - arm_smmu_init_initial_stes(cfg->linear.table, cfg->linear.num_ents); return 0; }
static int arm_smmu_init_strtab(struct arm_smmu_device *smmu) { - u64 reg; int ret;
- if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) { + if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) ret = arm_smmu_init_strtab_2lvl(smmu); - reg = smmu->strtab_cfg.l2.l1_dma & STRTAB_BASE_ADDR_MASK; - } else { + else ret = arm_smmu_init_strtab_linear(smmu); - reg = smmu->strtab_cfg.linear.ste_dma & STRTAB_BASE_ADDR_MASK; - } if (ret) return ret;
- /* Set the strtab base address */ - reg |= STRTAB_BASE_RA; - smmu->strtab_cfg.strtab_base = reg; - ida_init(&smmu->vmid_map);
return 0; @@ -4564,6 +4542,30 @@ static int arm_smmu_ecmdq_reset(struct arm_smmu_device *smmu) } #endif
+static void arm_smmu_write_strtab(struct arm_smmu_device *smmu) +{ + struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; + dma_addr_t dma; + u32 reg; + + if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) { + reg = FIELD_PREP(STRTAB_BASE_CFG_FMT, + STRTAB_BASE_CFG_FMT_2LVL) | + FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, + ilog2(cfg->l2.num_l1_ents) + STRTAB_SPLIT) | + FIELD_PREP(STRTAB_BASE_CFG_SPLIT, STRTAB_SPLIT); + dma = cfg->l2.l1_dma; + } else { + reg = FIELD_PREP(STRTAB_BASE_CFG_FMT, + STRTAB_BASE_CFG_FMT_LINEAR) | + FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, smmu->sid_bits); + dma = cfg->linear.ste_dma; + } + writeq_relaxed((dma & STRTAB_BASE_ADDR_MASK) | STRTAB_BASE_RA, + smmu->base + ARM_SMMU_STRTAB_BASE); + writel_relaxed(reg, smmu->base + ARM_SMMU_STRTAB_BASE_CFG); +} + static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool resume) { int ret; @@ -4599,10 +4601,7 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool resume) writel_relaxed(reg, smmu->base + ARM_SMMU_CR2);
/* Stream table */ - writeq_relaxed(smmu->strtab_cfg.strtab_base, - smmu->base + ARM_SMMU_STRTAB_BASE); - writel_relaxed(smmu->strtab_cfg.strtab_base_cfg, - smmu->base + ARM_SMMU_STRTAB_BASE_CFG); + arm_smmu_write_strtab(smmu);
/* Command queue */ writeq_relaxed(smmu->cmdq.q.q_base, smmu->base + ARM_SMMU_CMDQ_BASE); diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h index ff1c87300775..9b19a9407afc 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h @@ -693,8 +693,6 @@ struct arm_smmu_strtab_cfg { unsigned int num_l1_ents; } l2; }; - u64 strtab_base; - u32 strtab_base_cfg; };
/* An SMMUv3 instance */