[PATCH v2 1/4] iommu/arm-smmu: Simplify ASID/VMID handling
Jordan Crouse
jcrouse at codeaurora.org
Thu Mar 30 11:37:13 PDT 2017
On Thu, Mar 30, 2017 at 05:56:29PM +0100, Robin Murphy wrote:
> Calculating ASIDs/VMIDs dynamically from arm_smmu_cfg was a neat trick,
> but the global uniqueness workaround makes it somewhat more awkward, and
> means we end up having to pass extra state around in certain cases just
> to keep a handle on the offset.
>
> We already have 16 bits going spare in arm_smmu_cfg; let's just
> precalculate an ASID/VMID, plop it in there, and tidy up the users
> accordingly. We'd also need something like this anyway if we ever get
> near to thinking about SVM, so it's no bad thing.
If it helps:
Reviewed-by: Jordan Crouse <jcrouse at codeaurora.org>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
>
> v2: No change
>
> drivers/iommu/arm-smmu.c | 36 +++++++++++++++++++-----------------
> 1 file changed, 19 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index abf6496843a6..34b745bf59f2 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -404,14 +404,15 @@ enum arm_smmu_context_fmt {
> struct arm_smmu_cfg {
> u8 cbndx;
> u8 irptndx;
> + union {
> + u16 asid;
> + u16 vmid;
> + };
> u32 cbar;
> enum arm_smmu_context_fmt fmt;
> };
> #define INVALID_IRPTNDX 0xff
>
> -#define ARM_SMMU_CB_ASID(smmu, cfg) ((u16)(smmu)->cavium_id_base + (cfg)->cbndx)
> -#define ARM_SMMU_CB_VMID(smmu, cfg) ((u16)(smmu)->cavium_id_base + (cfg)->cbndx + 1)
> -
> enum arm_smmu_domain_stage {
> ARM_SMMU_DOMAIN_S1 = 0,
> ARM_SMMU_DOMAIN_S2,
> @@ -603,12 +604,10 @@ static void arm_smmu_tlb_inv_context(void *cookie)
>
> if (stage1) {
> base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
> - writel_relaxed(ARM_SMMU_CB_ASID(smmu, cfg),
> - base + ARM_SMMU_CB_S1_TLBIASID);
> + writel_relaxed(cfg->asid, base + ARM_SMMU_CB_S1_TLBIASID);
> } else {
> base = ARM_SMMU_GR0(smmu);
> - writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg),
> - base + ARM_SMMU_GR0_TLBIVMID);
> + writel_relaxed(cfg->vmid, base + ARM_SMMU_GR0_TLBIVMID);
> }
>
> __arm_smmu_tlb_sync(smmu);
> @@ -629,14 +628,14 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
>
> if (cfg->fmt != ARM_SMMU_CTX_FMT_AARCH64) {
> iova &= ~12UL;
> - iova |= ARM_SMMU_CB_ASID(smmu, cfg);
> + iova |= cfg->asid;
> do {
> writel_relaxed(iova, reg);
> iova += granule;
> } while (size -= granule);
> } else {
> iova >>= 12;
> - iova |= (u64)ARM_SMMU_CB_ASID(smmu, cfg) << 48;
> + iova |= (u64)cfg->asid << 48;
> do {
> writeq_relaxed(iova, reg);
> iova += granule >> 12;
> @@ -653,7 +652,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
> } while (size -= granule);
> } else {
> reg = ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_TLBIVMID;
> - writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg), reg);
> + writel_relaxed(cfg->vmid, reg);
> }
> }
>
> @@ -735,7 +734,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
> reg = CBA2R_RW64_32BIT;
> /* 16-bit VMIDs live in CBA2R */
> if (smmu->features & ARM_SMMU_FEAT_VMID16)
> - reg |= ARM_SMMU_CB_VMID(smmu, cfg) << CBA2R_VMID_SHIFT;
> + reg |= cfg->vmid << CBA2R_VMID_SHIFT;
>
> writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBA2R(cfg->cbndx));
> }
> @@ -754,26 +753,24 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
> (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
> } else if (!(smmu->features & ARM_SMMU_FEAT_VMID16)) {
> /* 8-bit VMIDs live in CBAR */
> - reg |= ARM_SMMU_CB_VMID(smmu, cfg) << CBAR_VMID_SHIFT;
> + reg |= cfg->vmid << CBAR_VMID_SHIFT;
> }
> writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(cfg->cbndx));
>
> /* TTBRs */
> if (stage1) {
> - u16 asid = ARM_SMMU_CB_ASID(smmu, cfg);
> -
> if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
> reg = pgtbl_cfg->arm_v7s_cfg.ttbr[0];
> writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0);
> reg = pgtbl_cfg->arm_v7s_cfg.ttbr[1];
> writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1);
> - writel_relaxed(asid, cb_base + ARM_SMMU_CB_CONTEXTIDR);
> + writel_relaxed(cfg->asid, cb_base + ARM_SMMU_CB_CONTEXTIDR);
> } else {
> reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
> - reg64 |= (u64)asid << TTBRn_ASID_SHIFT;
> + reg64 |= (u64)cfg->asid << TTBRn_ASID_SHIFT;
> writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR0);
> reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
> - reg64 |= (u64)asid << TTBRn_ASID_SHIFT;
> + reg64 |= (u64)cfg->asid << TTBRn_ASID_SHIFT;
> writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR1);
> }
> } else {
> @@ -941,6 +938,11 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
> cfg->irptndx = cfg->cbndx;
> }
>
> + if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2)
> + cfg->vmid = cfg->cbndx + 1 + smmu->cavium_id_base;
> + else
> + cfg->asid = cfg->cbndx + smmu->cavium_id_base;
> +
> pgtbl_cfg = (struct io_pgtable_cfg) {
> .pgsize_bitmap = smmu->pgsize_bitmap,
> .ias = ias,
> --
> 2.11.0.dirty
>
> _______________________________________________
> iommu mailing list
> iommu at lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
More information about the linux-arm-kernel
mailing list