From: Robin Murphy <robin.murphy@arm.com> To: will@kernel.org Cc: bjorn.andersson@linaro.org, iommu@lists.linux-foundation.org, gregory.clement@bootlin.com, linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 17/17] iommu/arm-smmu: Add context init implementation hook Date: Thu, 15 Aug 2019 19:37:37 +0100 Message-ID: <f50c14834bb7a4f0f7c765d433c2defdb03661c9.1565892337.git.robin.murphy@arm.com> (raw) In-Reply-To: <cover.1565892337.git.robin.murphy@arm.com> Allocating and initialising a context for a domain is another point where certain implementations are known to want special behaviour. Currently the other half of the Cavium workaround comes into play here, so let's finish the job to get the whole thing right out of the way. Signed-off-by: Robin Murphy <robin.murphy@arm.com> --- drivers/iommu/arm-smmu-impl.c | 42 ++++++++++++++++++++++++++--- drivers/iommu/arm-smmu.c | 51 +++++++---------------------------- drivers/iommu/arm-smmu.h | 42 +++++++++++++++++++++++++++-- 3 files changed, 87 insertions(+), 48 deletions(-) diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c index 4dc8b1c4befb..e22e9004f449 100644 --- a/drivers/iommu/arm-smmu-impl.c +++ b/drivers/iommu/arm-smmu-impl.c @@ -48,25 +48,60 @@ const struct arm_smmu_impl calxeda_impl = { }; +struct cavium_smmu { + struct arm_smmu_device smmu; + u32 id_base; +}; + static int cavium_cfg_probe(struct arm_smmu_device *smmu) { static atomic_t context_count = ATOMIC_INIT(0); + struct cavium_smmu *cs = container_of(smmu, struct cavium_smmu, smmu); /* * Cavium CN88xx erratum #27704. * Ensure ASID and VMID allocation is unique across all SMMUs in * the system. */ - smmu->cavium_id_base = atomic_fetch_add(smmu->num_context_banks, - &context_count); + cs->id_base = atomic_fetch_add(smmu->num_context_banks, &context_count); dev_notice(smmu->dev, "\tenabling workaround for Cavium erratum 27704\n"); return 0; } +int cavium_init_context(struct arm_smmu_domain *smmu_domain) +{ + struct cavium_smmu *cs = container_of(smmu_domain->smmu, + struct cavium_smmu, smmu); + + if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2) + smmu_domain->cfg.vmid += cs->id_base; + else + smmu_domain->cfg.asid += cs->id_base; + + return 0; +} + const struct arm_smmu_impl cavium_impl = { .cfg_probe = cavium_cfg_probe, + .init_context = cavium_init_context, }; +struct arm_smmu_device *cavium_smmu_impl_init(struct arm_smmu_device *smmu) +{ + struct cavium_smmu *cs; + + cs = devm_kzalloc(smmu->dev, sizeof(*cs), GFP_KERNEL); + if (!cs) + return ERR_PTR(-ENOMEM); + + cs->smmu = *smmu; + cs->smmu.impl = &cavium_impl; + + devm_kfree(smmu->dev, smmu); + + return &cs->smmu; +} + #define ARM_MMU500_ACTLR_CPRE (1 << 1) @@ -126,8 +161,7 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu) smmu->impl = &arm_mmu500_impl; break; case CAVIUM_SMMUV2: - smmu->impl = &cavium_impl; - break; + return cavium_smmu_impl_init(smmu); default: break; } diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index fc98992d120d..b8628e2ab579 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -27,7 +27,6 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/io-64-nonatomic-hi-lo.h> -#include <linux/io-pgtable.h> #include <linux/iopoll.h> #include <linux/init.h> #include <linux/moduleparam.h> @@ -111,44 +110,6 @@ struct arm_smmu_master_cfg { #define for_each_cfg_sme(fw, i, idx) \ for (i = 0; idx = fwspec_smendx(fw, i), i < fw->num_ids; ++i) -enum arm_smmu_context_fmt { - ARM_SMMU_CTX_FMT_NONE, - ARM_SMMU_CTX_FMT_AARCH64, - ARM_SMMU_CTX_FMT_AARCH32_L, - ARM_SMMU_CTX_FMT_AARCH32_S, -}; - -struct arm_smmu_cfg { - u8 cbndx; - u8 irptndx; - union { - u16 asid; - u16 vmid; - }; - enum arm_smmu_cbar_type cbar; - enum arm_smmu_context_fmt fmt; -}; -#define INVALID_IRPTNDX 0xff - -enum arm_smmu_domain_stage { - ARM_SMMU_DOMAIN_S1 = 0, - ARM_SMMU_DOMAIN_S2, - ARM_SMMU_DOMAIN_NESTED, - ARM_SMMU_DOMAIN_BYPASS, -}; - -struct arm_smmu_domain { - struct arm_smmu_device *smmu; - struct io_pgtable_ops *pgtbl_ops; - const struct iommu_gather_ops *tlb_ops; - struct arm_smmu_cfg cfg; - enum arm_smmu_domain_stage stage; - bool non_strict; - struct mutex init_mutex; /* Protects smmu pointer */ - spinlock_t cb_lock; /* Serialises ATS1* ops and TLB syncs */ - struct iommu_domain domain; -}; - static bool using_legacy_binding, using_generic_binding; static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu) @@ -749,9 +710,16 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, } if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2) - cfg->vmid = cfg->cbndx + 1 + smmu->cavium_id_base; + cfg->vmid = cfg->cbndx + 1; else - cfg->asid = cfg->cbndx + smmu->cavium_id_base; + cfg->asid = cfg->cbndx; + + smmu_domain->smmu = smmu; + if (smmu->impl && smmu->impl->init_context) { + ret = smmu->impl->init_context(smmu_domain); + if (ret) + goto out_unlock; + } pgtbl_cfg = (struct io_pgtable_cfg) { .pgsize_bitmap = smmu->pgsize_bitmap, @@ -765,7 +733,6 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, if (smmu_domain->non_strict) pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT; - smmu_domain->smmu = smmu; pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain); if (!pgtbl_ops) { ret = -ENOMEM; diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h index ddafe872a396..611ed742e56f 100644 --- a/drivers/iommu/arm-smmu.h +++ b/drivers/iommu/arm-smmu.h @@ -14,6 +14,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/device.h> +#include <linux/io-pgtable.h> #include <linux/iommu.h> #include <linux/mutex.h> #include <linux/spinlock.h> @@ -270,14 +271,50 @@ struct arm_smmu_device { struct clk_bulk_data *clks; int num_clks; - u32 cavium_id_base; /* Specific to Cavium */ - spinlock_t global_sync_lock; /* IOMMU core code handle */ struct iommu_device iommu; }; +enum arm_smmu_context_fmt { + ARM_SMMU_CTX_FMT_NONE, + ARM_SMMU_CTX_FMT_AARCH64, + ARM_SMMU_CTX_FMT_AARCH32_L, + ARM_SMMU_CTX_FMT_AARCH32_S, +}; + +struct arm_smmu_cfg { + u8 cbndx; + u8 irptndx; + union { + u16 asid; + u16 vmid; + }; + enum arm_smmu_cbar_type cbar; + enum arm_smmu_context_fmt fmt; +}; +#define INVALID_IRPTNDX 0xff + +enum arm_smmu_domain_stage { + ARM_SMMU_DOMAIN_S1 = 0, + ARM_SMMU_DOMAIN_S2, + ARM_SMMU_DOMAIN_NESTED, + ARM_SMMU_DOMAIN_BYPASS, +}; + +struct arm_smmu_domain { + struct arm_smmu_device *smmu; + struct io_pgtable_ops *pgtbl_ops; + const struct iommu_gather_ops *tlb_ops; + struct arm_smmu_cfg cfg; + enum arm_smmu_domain_stage stage; + bool non_strict; + struct mutex init_mutex; /* Protects smmu pointer */ + spinlock_t cb_lock; /* Serialises ATS1* ops and TLB syncs */ + struct iommu_domain domain; +}; + /* Implementation details, yay! */ struct arm_smmu_impl { @@ -289,6 +326,7 @@ struct arm_smmu_impl { u64 val); int (*cfg_probe)(struct arm_smmu_device *smmu); int (*reset)(struct arm_smmu_device *smmu); + int (*init_context)(struct arm_smmu_domain *smmu_domain); }; static inline void __iomem *arm_smmu_page(struct arm_smmu_device *smmu, int n) -- 2.21.0.dirty _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
next prev parent reply index Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-08-15 18:37 [PATCH v2 00/17] Arm SMMU refactoring Robin Murphy 2019-08-15 18:37 ` [PATCH v2 01/17] iommu/arm-smmu: Mask TLBI address correctly Robin Murphy 2019-08-15 18:37 ` [PATCH v2 02/17] iommu/qcom: Mask TLBI addresses correctly Robin Murphy 2019-08-15 18:37 ` [PATCH v2 03/17] iommu/arm-smmu: Convert GR0 registers to bitfields Robin Murphy 2019-08-15 18:37 ` [PATCH v2 04/17] iommu/arm-smmu: Convert GR1 " Robin Murphy 2019-08-15 18:37 ` [PATCH v2 05/17] iommu/arm-smmu: Convert context bank " Robin Murphy 2019-08-15 18:37 ` [PATCH v2 06/17] iommu/arm-smmu: Rework cb_base handling Robin Murphy 2019-08-15 18:37 ` [PATCH v2 07/17] iommu/arm-smmu: Split arm_smmu_tlb_inv_range_nosync() Robin Murphy 2019-08-15 18:37 ` [PATCH v2 08/17] iommu/arm-smmu: Get rid of weird "atomic" write Robin Murphy 2019-08-15 18:37 ` [PATCH v2 09/17] iommu/arm-smmu: Abstract GR1 accesses Robin Murphy 2019-08-15 18:37 ` [PATCH v2 10/17] iommu/arm-smmu: Abstract context bank accesses Robin Murphy 2019-08-15 18:37 ` [PATCH v2 11/17] iommu/arm-smmu: Abstract GR0 accesses Robin Murphy 2019-08-15 18:37 ` [PATCH v2 12/17] iommu/arm-smmu: Rename arm-smmu-regs.h Robin Murphy 2019-08-15 18:37 ` [PATCH v2 13/17] iommu/arm-smmu: Add implementation infrastructure Robin Murphy 2019-08-15 18:37 ` [PATCH v2 14/17] iommu/arm-smmu: Move Secure access quirk to implementation Robin Murphy 2019-08-15 18:37 ` [PATCH v2 15/17] iommu/arm-smmu: Add configuration implementation hook Robin Murphy 2019-08-15 18:37 ` [PATCH v2 16/17] iommu/arm-smmu: Add reset " Robin Murphy 2019-08-15 18:37 ` Robin Murphy [this message] 2019-08-20 10:15 ` [PATCH v2 17/17] iommu/arm-smmu: Add context init " Vivek Gautam 2019-08-20 13:00 ` Robin Murphy 2019-08-19 15:56 ` [PATCH v2 00/17] Arm SMMU refactoring Will Deacon 2019-08-19 18:10 ` Robin Murphy 2019-08-20 7:04 ` Will Deacon 2019-08-20 8:20 ` Vivek Gautam
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=f50c14834bb7a4f0f7c765d433c2defdb03661c9.1565892337.git.robin.murphy@arm.com \ --to=robin.murphy@arm.com \ --cc=bjorn.andersson@linaro.org \ --cc=gregory.clement@bootlin.com \ --cc=iommu@lists.linux-foundation.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=will@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
IOMMU Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/linux-iommu/0 linux-iommu/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 linux-iommu linux-iommu/ https://lore.kernel.org/linux-iommu \ iommu@lists.linux-foundation.org public-inbox-index linux-iommu Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.linux-foundation.lists.iommu AGPL code for this site: git clone https://public-inbox.org/public-inbox.git