From: kholk11@gmail.com To: linux-arm-msm@vger.kernel.org Cc: kholk11@gmail.com, iommu@lists.linux-foundation.org, marijns95@gmail.com, agross@kernel.org, robdclark@gmail.com, joro@8bytes.org Subject: [PATCH v4 5/7] iommu/qcom: Add support for AArch64 IOMMU pagetables Date: Wed, 2 Oct 2019 00:02:03 +0200 [thread overview] Message-ID: <20191001220205.6423-6-kholk11@gmail.com> (raw) In-Reply-To: <20191001220205.6423-1-kholk11@gmail.com> From: AngeloGioacchino Del Regno <kholk11@gmail.com> Some IOMMUs associated with some TZ firmwares may support switching to the AArch64 pagetable format by sending a "set pagetable format" scm command indicating the IOMMU secure ID and the context number to switch. Add a DT property "qcom,use-aarch64-pagetables" for this driver to send this command to the secure world and to switch the pagetable format to benefit of the ARM64 IOMMU pagetables, where possible. Note that, even though the command should be valid to switch each context, the property is made global because: 1. It doesn't make too much sense to switch only one or two context(s) to AA64 instead of just the entire thing 2. Some IOMMUs will go crazy and produce spectacular results when trying to mix up the pagetables on a per-context basis. Signed-off-by: AngeloGioacchino Del Regno <kholk11@gmail.com> --- .../devicetree/bindings/iommu/qcom,iommu.txt | 2 + drivers/iommu/qcom_iommu.c | 55 +++++++++++++++---- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt index ba0b77889f02..72ae0595efff 100644 --- a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt +++ b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt @@ -47,6 +47,8 @@ to non-secure vs secure interrupt line. secure lines. (Ie. if the iommu contains secure context banks) - qcom,ctx-num : The number associated to the context bank +- qcom,use-aarch64-pagetables : Switch to AArch64 pagetable format on all + contexts declared in this IOMMU ** Examples: diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c index b4a38ef129e3..dac77dbec0f0 100644 --- a/drivers/iommu/qcom_iommu.c +++ b/drivers/iommu/qcom_iommu.c @@ -48,6 +48,7 @@ struct qcom_iommu_dev { void __iomem *local_base; u32 sec_id; u8 num_ctxs; + bool use_aarch64_pt; struct qcom_iommu_ctx *ctxs[0]; /* indexed by asid-1 */ }; @@ -153,11 +154,17 @@ static void qcom_iommu_tlb_inv_range_nosync(unsigned long iova, size_t size, reg = leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA; for (i = 0; i < fwspec->num_ids; i++) { + struct qcom_iommu_dev *qcom_iommu = to_iommu(fwspec); struct qcom_iommu_ctx *ctx = to_ctx(fwspec, fwspec->ids[i]); size_t s = size; - iova = (iova >> 12) << 12; - iova |= ctx->asid; + if (qcom_iommu->use_aarch64_pt) { + iova >>= 12; + iova |= (u64)ctx->asid << 48; + } else { + iova = (iova >> 12) << 12; + iova |= ctx->asid; + } do { iommu_writel(ctx, reg, iova); iova += granule; @@ -244,6 +251,8 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain); struct io_pgtable_ops *pgtbl_ops; struct io_pgtable_cfg pgtbl_cfg; + enum io_pgtable_fmt pgtbl_fmt; + unsigned long ias, oas; int i, ret = 0; u32 reg; @@ -251,16 +260,25 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, if (qcom_domain->iommu) goto out_unlock; + if (qcom_iommu->use_aarch64_pt) { + pgtbl_fmt = ARM_64_LPAE_S1; + ias = oas = 48; + } else { + pgtbl_fmt = ARM_32_LPAE_S1; + ias = 32; + oas = 40; + } + pgtbl_cfg = (struct io_pgtable_cfg) { .pgsize_bitmap = qcom_iommu_ops.pgsize_bitmap, - .ias = 32, - .oas = 40, + .ias = ias, + .oas = oas, .tlb = &qcom_flush_ops, .iommu_dev = qcom_iommu->dev, }; qcom_domain->iommu = qcom_iommu; - pgtbl_ops = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &pgtbl_cfg, fwspec); + pgtbl_ops = alloc_io_pgtable_ops(pgtbl_fmt, &pgtbl_cfg, fwspec); if (!pgtbl_ops) { dev_err(qcom_iommu->dev, "failed to allocate pagetable ops\n"); ret = -ENOMEM; @@ -274,6 +292,7 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, for (i = 0; i < fwspec->num_ids; i++) { struct qcom_iommu_ctx *ctx = to_ctx(fwspec, fwspec->ids[i]); + u32 tcr[2]; if (!ctx->secure_init) { ret = qcom_scm_restore_sec_cfg(qcom_iommu->sec_id, ctx->asid); @@ -286,12 +305,25 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, qcom_iommu_reset_ctx(ctx); + tcr[0] = pgtbl_cfg.arm_lpae_s1_cfg.tcr; + tcr[1] = pgtbl_cfg.arm_lpae_s1_cfg.tcr >> 32; + tcr[1] |= FIELD_PREP(TCR2_SEP, TCR2_SEP_UPSTREAM); + + if (qcom_iommu->use_aarch64_pt) { + /* This shall not fail, or spectacular things happen */ + if (qcom_scm_iommu_set_pt_format(qcom_iommu->sec_id, + ctx->asid, 1)) { + dev_warn(qcom_iommu->dev, + "Cannot set AArch64 pt format\n"); + goto out_clear_iommu; + } + + tcr[1] |= TCR2_AS; + } + /* TCR */ - iommu_writel(ctx, ARM_SMMU_CB_TCR2, - (pgtbl_cfg.arm_lpae_s1_cfg.tcr >> 32) | - FIELD_PREP(TCR2_SEP, TCR2_SEP_UPSTREAM)); - iommu_writel(ctx, ARM_SMMU_CB_TCR, - pgtbl_cfg.arm_lpae_s1_cfg.tcr); + iommu_writel(ctx, ARM_SMMU_CB_TCR2, tcr[1]); + iommu_writel(ctx, ARM_SMMU_CB_TCR, tcr[0]); /* TTBRs */ iommu_writeq(ctx, ARM_SMMU_CB_TTBR0, @@ -869,6 +901,9 @@ static int qcom_iommu_device_probe(struct platform_device *pdev) return -ENODEV; } + if (of_property_read_bool(dev->of_node, "qcom,use-aarch64-pagetables")) + qcom_iommu->use_aarch64_pt = true; + if (qcom_iommu_has_secure_context(qcom_iommu)) { ret = qcom_iommu_sec_ptbl_init(dev); if (ret) { -- 2.21.0
WARNING: multiple messages have this Message-ID (diff)
From: kholk11@gmail.com To: linux-arm-msm@vger.kernel.org Cc: marijns95@gmail.com, iommu@lists.linux-foundation.org, agross@kernel.org, kholk11@gmail.com Subject: [PATCH v4 5/7] iommu/qcom: Add support for AArch64 IOMMU pagetables Date: Wed, 2 Oct 2019 00:02:03 +0200 [thread overview] Message-ID: <20191001220205.6423-6-kholk11@gmail.com> (raw) In-Reply-To: <20191001220205.6423-1-kholk11@gmail.com> From: AngeloGioacchino Del Regno <kholk11@gmail.com> Some IOMMUs associated with some TZ firmwares may support switching to the AArch64 pagetable format by sending a "set pagetable format" scm command indicating the IOMMU secure ID and the context number to switch. Add a DT property "qcom,use-aarch64-pagetables" for this driver to send this command to the secure world and to switch the pagetable format to benefit of the ARM64 IOMMU pagetables, where possible. Note that, even though the command should be valid to switch each context, the property is made global because: 1. It doesn't make too much sense to switch only one or two context(s) to AA64 instead of just the entire thing 2. Some IOMMUs will go crazy and produce spectacular results when trying to mix up the pagetables on a per-context basis. Signed-off-by: AngeloGioacchino Del Regno <kholk11@gmail.com> --- .../devicetree/bindings/iommu/qcom,iommu.txt | 2 + drivers/iommu/qcom_iommu.c | 55 +++++++++++++++---- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt index ba0b77889f02..72ae0595efff 100644 --- a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt +++ b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt @@ -47,6 +47,8 @@ to non-secure vs secure interrupt line. secure lines. (Ie. if the iommu contains secure context banks) - qcom,ctx-num : The number associated to the context bank +- qcom,use-aarch64-pagetables : Switch to AArch64 pagetable format on all + contexts declared in this IOMMU ** Examples: diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c index b4a38ef129e3..dac77dbec0f0 100644 --- a/drivers/iommu/qcom_iommu.c +++ b/drivers/iommu/qcom_iommu.c @@ -48,6 +48,7 @@ struct qcom_iommu_dev { void __iomem *local_base; u32 sec_id; u8 num_ctxs; + bool use_aarch64_pt; struct qcom_iommu_ctx *ctxs[0]; /* indexed by asid-1 */ }; @@ -153,11 +154,17 @@ static void qcom_iommu_tlb_inv_range_nosync(unsigned long iova, size_t size, reg = leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA; for (i = 0; i < fwspec->num_ids; i++) { + struct qcom_iommu_dev *qcom_iommu = to_iommu(fwspec); struct qcom_iommu_ctx *ctx = to_ctx(fwspec, fwspec->ids[i]); size_t s = size; - iova = (iova >> 12) << 12; - iova |= ctx->asid; + if (qcom_iommu->use_aarch64_pt) { + iova >>= 12; + iova |= (u64)ctx->asid << 48; + } else { + iova = (iova >> 12) << 12; + iova |= ctx->asid; + } do { iommu_writel(ctx, reg, iova); iova += granule; @@ -244,6 +251,8 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain); struct io_pgtable_ops *pgtbl_ops; struct io_pgtable_cfg pgtbl_cfg; + enum io_pgtable_fmt pgtbl_fmt; + unsigned long ias, oas; int i, ret = 0; u32 reg; @@ -251,16 +260,25 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, if (qcom_domain->iommu) goto out_unlock; + if (qcom_iommu->use_aarch64_pt) { + pgtbl_fmt = ARM_64_LPAE_S1; + ias = oas = 48; + } else { + pgtbl_fmt = ARM_32_LPAE_S1; + ias = 32; + oas = 40; + } + pgtbl_cfg = (struct io_pgtable_cfg) { .pgsize_bitmap = qcom_iommu_ops.pgsize_bitmap, - .ias = 32, - .oas = 40, + .ias = ias, + .oas = oas, .tlb = &qcom_flush_ops, .iommu_dev = qcom_iommu->dev, }; qcom_domain->iommu = qcom_iommu; - pgtbl_ops = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &pgtbl_cfg, fwspec); + pgtbl_ops = alloc_io_pgtable_ops(pgtbl_fmt, &pgtbl_cfg, fwspec); if (!pgtbl_ops) { dev_err(qcom_iommu->dev, "failed to allocate pagetable ops\n"); ret = -ENOMEM; @@ -274,6 +292,7 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, for (i = 0; i < fwspec->num_ids; i++) { struct qcom_iommu_ctx *ctx = to_ctx(fwspec, fwspec->ids[i]); + u32 tcr[2]; if (!ctx->secure_init) { ret = qcom_scm_restore_sec_cfg(qcom_iommu->sec_id, ctx->asid); @@ -286,12 +305,25 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, qcom_iommu_reset_ctx(ctx); + tcr[0] = pgtbl_cfg.arm_lpae_s1_cfg.tcr; + tcr[1] = pgtbl_cfg.arm_lpae_s1_cfg.tcr >> 32; + tcr[1] |= FIELD_PREP(TCR2_SEP, TCR2_SEP_UPSTREAM); + + if (qcom_iommu->use_aarch64_pt) { + /* This shall not fail, or spectacular things happen */ + if (qcom_scm_iommu_set_pt_format(qcom_iommu->sec_id, + ctx->asid, 1)) { + dev_warn(qcom_iommu->dev, + "Cannot set AArch64 pt format\n"); + goto out_clear_iommu; + } + + tcr[1] |= TCR2_AS; + } + /* TCR */ - iommu_writel(ctx, ARM_SMMU_CB_TCR2, - (pgtbl_cfg.arm_lpae_s1_cfg.tcr >> 32) | - FIELD_PREP(TCR2_SEP, TCR2_SEP_UPSTREAM)); - iommu_writel(ctx, ARM_SMMU_CB_TCR, - pgtbl_cfg.arm_lpae_s1_cfg.tcr); + iommu_writel(ctx, ARM_SMMU_CB_TCR2, tcr[1]); + iommu_writel(ctx, ARM_SMMU_CB_TCR, tcr[0]); /* TTBRs */ iommu_writeq(ctx, ARM_SMMU_CB_TTBR0, @@ -869,6 +901,9 @@ static int qcom_iommu_device_probe(struct platform_device *pdev) return -ENODEV; } + if (of_property_read_bool(dev->of_node, "qcom,use-aarch64-pagetables")) + qcom_iommu->use_aarch64_pt = true; + if (qcom_iommu_has_secure_context(qcom_iommu)) { ret = qcom_iommu_sec_ptbl_init(dev); if (ret) { -- 2.21.0 _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
next prev parent reply other threads:[~2019-10-01 22:02 UTC|newest] Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-10-01 22:01 [PATCH v4 0/7] Add support for QCOM IOMMU v2 and 500 kholk11 2019-10-01 22:01 ` kholk11 2019-10-01 22:01 ` [PATCH v4 1/7] firmware: qcom: scm: Add function to set IOMMU pagetable addressing kholk11 2019-10-01 22:01 ` kholk11 2019-10-15 11:14 ` Joerg Roedel 2019-10-15 11:14 ` Joerg Roedel 2019-10-15 12:33 ` AngeloGioacchino Del Regno 2019-10-15 12:33 ` AngeloGioacchino Del Regno 2019-10-15 12:40 ` Joerg Roedel 2019-10-15 12:40 ` Joerg Roedel 2019-10-15 13:09 ` AngeloGioacchino Del Regno 2019-10-15 13:09 ` AngeloGioacchino Del Regno 2019-10-01 22:02 ` [PATCH v4 2/7] iommu/qcom: Use the asid read from device-tree if specified kholk11 2019-10-01 22:02 ` kholk11 2019-10-15 12:09 ` Robin Murphy 2019-10-15 12:09 ` Robin Murphy 2019-10-15 13:06 ` AngeloGioacchino Del Regno 2019-10-15 13:06 ` AngeloGioacchino Del Regno 2019-10-01 22:02 ` [PATCH v4 3/7] iommu/qcom: Write TCR before TTBRs to fix ASID access behavior kholk11 2019-10-01 22:02 ` kholk11 2019-10-01 22:02 ` [PATCH v4 4/7] iommu/qcom: Properly reset the IOMMU context kholk11 2019-10-01 22:02 ` kholk11 2019-10-02 11:29 ` Robin Murphy 2019-10-02 11:29 ` Robin Murphy 2019-10-01 22:02 ` kholk11 [this message] 2019-10-01 22:02 ` [PATCH v4 5/7] iommu/qcom: Add support for AArch64 IOMMU pagetables kholk11 2019-10-01 22:02 ` [PATCH v4 6/7] iommu/qcom: Index contexts by asid number to allow asid 0 kholk11 2019-10-01 22:02 ` kholk11 2019-10-01 22:02 ` [PATCH v4 7/7] iommu/qcom: Add support for QCIOMMUv2 and QCIOMMU-500 secured contexts kholk11 2019-10-01 22:02 ` kholk11 2019-10-05 4:56 ` [PATCH v4 0/7] Add support for QCOM IOMMU v2 and 500 Bjorn Andersson 2019-10-05 4:56 ` Bjorn Andersson 2019-10-05 9:32 ` AngeloGioacchino Del Regno 2019-10-05 9:32 ` AngeloGioacchino Del Regno
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=20191001220205.6423-6-kholk11@gmail.com \ --to=kholk11@gmail.com \ --cc=agross@kernel.org \ --cc=iommu@lists.linux-foundation.org \ --cc=joro@8bytes.org \ --cc=linux-arm-msm@vger.kernel.org \ --cc=marijns95@gmail.com \ --cc=robdclark@gmail.com \ /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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.