iommu.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support
@ 2020-06-11 22:21 Jordan Crouse
  2020-06-11 22:21 ` [PATCH v8 1/7] iommu/arm-smmu: Pass io-pgtable config to implementation specific function Jordan Crouse
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Sean Paul, linux-kernel, linux-arm-kernel, Will Deacon,
	Jeffrey Hugo, David Airlie, Robin Murphy, Douglas Anderson,
	Rob Herring, Bjorn Andersson, iommu, Andy Gross, dri-devel,
	Daniel Vetter, Thomas Gleixner, Shawn Guo, freedreno, devicetree,
	Brian Masney


Another iteration of the split-pagetable support for arm-smmu and the Adreno GPU
SMMU. After email discussions [1] we opted to make a arm-smmu implementation for
specifically for the Adreno GPU and use that to enable split pagetable support
and later other implementation specific bits that we need.

On the hardware side this is very close to the same code from before [2] only
the TTBR1 quirk is turned on by the implementation and not a domain attribute.
In drm/msm we use the returned size of the aperture as a clue to let us know
which virtual address space we should use for global memory objects.

There are two open items that you should be aware of. First, in the
implementation specific code we have to check the compatible string of the
device so that we only enable TTBR1 for the GPU (SID 0) and not the GMU (SID 4).
I went back and forth trying to decide if I wanted to use the compatbile string
or the SID as the filter and settled on the compatible string but I could be
talked out of it.

The other open item is that in drm/msm the hardware only uses 49 bits of the
address space but arm-smmu expects the address to be sign extended all the way
to 64 bits. This isn't a problem normally unless you look at the hardware
registers that contain a IOVA and then the upper bits will be zero. I opted to
restrict the internal drm/msm IOVA range to only 49 bits and then sign extend
right before calling iommu_map / iommu_unmap. This is a bit wonky but I thought
that matching the hardware would be less confusing when debugging a hang.

v8: Pass the attached device in the smmu_domain to the implementation
specific functions

[1] https://lists.linuxfoundation.org/pipermail/iommu/2020-May/044537.html
[2] https://patchwork.kernel.org/patch/11482591/


Jordan Crouse (7):
  iommu/arm-smmu: Pass io-pgtable config to implementation specific
    function
  iommu/arm-smmu: Add support for split pagetables
  dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU
  iommu/arm-smmu: Add a pointer to the attached device to smmu_domain
  iommu/arm-smmu: Add implementation for the adreno GPU SMMU
  drm/msm: Set the global virtual address range from the IOMMU domain
  arm: dts: qcom: sm845: Set the compatible string for the GPU SMMU

 .../devicetree/bindings/iommu/arm,smmu.yaml   |  4 ++
 arch/arm64/boot/dts/qcom/sdm845.dtsi          |  2 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.c       | 13 +++++-
 drivers/gpu/drm/msm/msm_iommu.c               |  7 +++
 drivers/iommu/arm-smmu-impl.c                 |  6 ++-
 drivers/iommu/arm-smmu-qcom.c                 | 45 ++++++++++++++++++-
 drivers/iommu/arm-smmu.c                      | 33 +++++++++-----
 drivers/iommu/arm-smmu.h                      | 30 ++++++++++---
 8 files changed, 117 insertions(+), 23 deletions(-)

-- 
2.17.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v8 1/7] iommu/arm-smmu: Pass io-pgtable config to implementation specific function
  2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
  2020-06-11 22:21 ` [PATCH v8 2/7] iommu/arm-smmu: Add support for split pagetables Jordan Crouse
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Will Deacon, freedreno, linux-kernel, iommu, Robin Murphy,
	linux-arm-kernel

Construct the io-pgtable config before calling the implementation specific
init_context function and pass it so the implementation specific function
can get a chance to change it before the io-pgtable is created.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---

 drivers/iommu/arm-smmu-impl.c |  3 ++-
 drivers/iommu/arm-smmu.c      | 11 ++++++-----
 drivers/iommu/arm-smmu.h      |  3 ++-
 3 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
index c75b9d957b70..a20e426d81ac 100644
--- a/drivers/iommu/arm-smmu-impl.c
+++ b/drivers/iommu/arm-smmu-impl.c
@@ -68,7 +68,8 @@ static int cavium_cfg_probe(struct arm_smmu_device *smmu)
 	return 0;
 }
 
-static int cavium_init_context(struct arm_smmu_domain *smmu_domain)
+static int cavium_init_context(struct arm_smmu_domain *smmu_domain,
+		struct io_pgtable_cfg *pgtbl_cfg)
 {
 	struct cavium_smmu *cs = container_of(smmu_domain->smmu,
 					      struct cavium_smmu, smmu);
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 243bc4cb2705..8a3a6c8c887a 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -797,11 +797,6 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
 		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,
@@ -812,6 +807,12 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
 		.iommu_dev	= smmu->dev,
 	};
 
+	if (smmu->impl && smmu->impl->init_context) {
+		ret = smmu->impl->init_context(smmu_domain, &pgtbl_cfg);
+		if (ret)
+			goto out_unlock;
+	}
+
 	if (smmu_domain->non_strict)
 		pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
 
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index d172c024be61..38b041530a4f 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -383,7 +383,8 @@ 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);
+	int (*init_context)(struct arm_smmu_domain *smmu_domain,
+			struct io_pgtable_cfg *cfg);
 	void (*tlb_sync)(struct arm_smmu_device *smmu, int page, int sync,
 			 int status);
 	int (*def_domain_type)(struct device *dev);
-- 
2.17.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 2/7] iommu/arm-smmu: Add support for split pagetables
  2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
  2020-06-11 22:21 ` [PATCH v8 1/7] iommu/arm-smmu: Pass io-pgtable config to implementation specific function Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
  2020-06-11 22:21 ` [PATCH v8 3/7] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU Jordan Crouse
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Will Deacon, freedreno, linux-kernel, iommu, Robin Murphy,
	linux-arm-kernel

Enable TTBR1 for a context bank if IO_PGTABLE_QUIRK_ARM_TTBR1 is selected
by the io-pgtable configuration.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---

 drivers/iommu/arm-smmu.c | 21 ++++++++++++++++-----
 drivers/iommu/arm-smmu.h | 25 +++++++++++++++++++------
 2 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 8a3a6c8c887a..048de2681670 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -555,11 +555,15 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
 			cb->ttbr[0] = pgtbl_cfg->arm_v7s_cfg.ttbr;
 			cb->ttbr[1] = 0;
 		} else {
-			cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
-			cb->ttbr[0] |= FIELD_PREP(ARM_SMMU_TTBRn_ASID,
-						  cfg->asid);
+			cb->ttbr[0] = FIELD_PREP(ARM_SMMU_TTBRn_ASID,
+				cfg->asid);
 			cb->ttbr[1] = FIELD_PREP(ARM_SMMU_TTBRn_ASID,
-						 cfg->asid);
+				cfg->asid);
+
+			if (pgtbl_cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1)
+				cb->ttbr[1] |= pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
+			else
+				cb->ttbr[0] |= pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
 		}
 	} else {
 		cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
@@ -824,7 +828,14 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
 
 	/* Update the domain's page sizes to reflect the page table format */
 	domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
-	domain->geometry.aperture_end = (1UL << ias) - 1;
+
+	if (pgtbl_cfg.quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) {
+		domain->geometry.aperture_start = ~0UL << ias;
+		domain->geometry.aperture_end = ~0UL;
+	} else {
+		domain->geometry.aperture_end = (1UL << ias) - 1;
+	}
+
 	domain->geometry.force_aperture = true;
 
 	/* Initialise the context bank with our page table cfg */
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index 38b041530a4f..5f2de20e883b 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -168,10 +168,12 @@ enum arm_smmu_cbar_type {
 #define ARM_SMMU_CB_TCR			0x30
 #define ARM_SMMU_TCR_EAE		BIT(31)
 #define ARM_SMMU_TCR_EPD1		BIT(23)
+#define ARM_SMMU_TCR_A1			BIT(22)
 #define ARM_SMMU_TCR_TG0		GENMASK(15, 14)
 #define ARM_SMMU_TCR_SH0		GENMASK(13, 12)
 #define ARM_SMMU_TCR_ORGN0		GENMASK(11, 10)
 #define ARM_SMMU_TCR_IRGN0		GENMASK(9, 8)
+#define ARM_SMMU_TCR_EPD0		BIT(7)
 #define ARM_SMMU_TCR_T0SZ		GENMASK(5, 0)
 
 #define ARM_SMMU_VTCR_RES1		BIT(31)
@@ -347,12 +349,23 @@ struct arm_smmu_domain {
 
 static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg *cfg)
 {
-	return ARM_SMMU_TCR_EPD1 |
-	       FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) |
-	       FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) |
-	       FIELD_PREP(ARM_SMMU_TCR_ORGN0, cfg->arm_lpae_s1_cfg.tcr.orgn) |
-	       FIELD_PREP(ARM_SMMU_TCR_IRGN0, cfg->arm_lpae_s1_cfg.tcr.irgn) |
-	       FIELD_PREP(ARM_SMMU_TCR_T0SZ, cfg->arm_lpae_s1_cfg.tcr.tsz);
+	u32 tcr = FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) |
+		FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) |
+		FIELD_PREP(ARM_SMMU_TCR_ORGN0, cfg->arm_lpae_s1_cfg.tcr.orgn) |
+		FIELD_PREP(ARM_SMMU_TCR_IRGN0, cfg->arm_lpae_s1_cfg.tcr.irgn) |
+		FIELD_PREP(ARM_SMMU_TCR_T0SZ, cfg->arm_lpae_s1_cfg.tcr.tsz);
+
+       /*
+	* When TTBR1 is selected shift the TCR fields by 16 bits and disable
+	* translation in TTBR0
+	*/
+	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) {
+		tcr = (tcr << 16) & ~ARM_SMMU_TCR_A1;
+		tcr |= ARM_SMMU_TCR_EPD0;
+	} else
+		tcr |= ARM_SMMU_TCR_EPD1;
+
+	return tcr;
 }
 
 static inline u32 arm_smmu_lpae_tcr2(struct io_pgtable_cfg *cfg)
-- 
2.17.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 3/7] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU
  2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
  2020-06-11 22:21 ` [PATCH v8 1/7] iommu/arm-smmu: Pass io-pgtable config to implementation specific function Jordan Crouse
  2020-06-11 22:21 ` [PATCH v8 2/7] iommu/arm-smmu: Add support for split pagetables Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
  2020-06-17 22:40   ` Rob Herring
  2020-06-11 22:21 ` [PATCH v8 4/7] iommu/arm-smmu: Add a pointer to the attached device to smmu_domain Jordan Crouse
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: devicetree, Will Deacon, freedreno, linux-kernel, iommu,
	Rob Herring, Robin Murphy, linux-arm-kernel

Every Qcom Adreno GPU has an embedded SMMU for its own use. These
devices depend on unique features such as split pagetables,
different stall/halt requirements and other settings. Identify them
with a compatible string so that they can be identified in the
arm-smmu implementation specific code.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---

 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index d7ceb4c34423..e52a1b146c97 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -38,6 +38,10 @@ properties:
               - qcom,sc7180-smmu-500
               - qcom,sdm845-smmu-500
           - const: arm,mmu-500
+      - description: Qcom Adreno GPUs implementing "arm,smmu-v2"
+        items:
+          - const: qcom,adreno-smmu
+          - const: qcom,smmu-v2
       - items:
           - const: arm,mmu-500
           - const: arm,smmu-v2
-- 
2.17.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 4/7] iommu/arm-smmu: Add a pointer to the attached device to smmu_domain
  2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
                   ` (2 preceding siblings ...)
  2020-06-11 22:21 ` [PATCH v8 3/7] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
  2020-06-12  4:19   ` kernel test robot
  2020-06-11 22:21 ` [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU Jordan Crouse
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Will Deacon, freedreno, linux-kernel, iommu, Robin Murphy,
	linux-arm-kernel

Add a link to the pointer to the struct device that is attached to a
domain. This makes it easy to get the pointer if it is needed in the
implementation specific code.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---

 drivers/iommu/arm-smmu.c | 1 +
 drivers/iommu/arm-smmu.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 048de2681670..743d75b9ff3f 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -801,6 +801,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
 		cfg->asid = cfg->cbndx;
 
 	smmu_domain->smmu = smmu;
+	smmu_domain->dev = dev;
 
 	pgtbl_cfg = (struct io_pgtable_cfg) {
 		.pgsize_bitmap	= smmu->pgsize_bitmap,
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index 5f2de20e883b..d33cfe26b2f5 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -345,6 +345,7 @@ struct arm_smmu_domain {
 	struct mutex			init_mutex; /* Protects smmu pointer */
 	spinlock_t			cb_lock; /* Serialises ATS1* ops and TLB syncs */
 	struct iommu_domain		domain;
+	struct device			*dev;	/* Device attached to this domain */
 };
 
 static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg *cfg)
-- 
2.17.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU
  2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
                   ` (3 preceding siblings ...)
  2020-06-11 22:21 ` [PATCH v8 4/7] iommu/arm-smmu: Add a pointer to the attached device to smmu_domain Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
  2020-06-12  5:11   ` kernel test robot
  2020-06-13  1:34   ` kernel test robot
  2020-06-11 22:21 ` [PATCH v8 6/7] drm/msm: Set the global virtual address range from the IOMMU domain Jordan Crouse
  2020-06-11 22:21 ` [PATCH v8 7/7] arm: dts: qcom: sm845: Set the compatible string for the GPU SMMU Jordan Crouse
  6 siblings, 2 replies; 13+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Will Deacon, freedreno, linux-kernel, iommu, Robin Murphy,
	linux-arm-kernel

Add a special implementation for the SMMU attached to most Adreno GPU
target triggered from the qcom,adreno-gpu-smmu compatible string. When
selected the driver will attempt to enable split pagetables.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---

 drivers/iommu/arm-smmu-impl.c |  3 +++
 drivers/iommu/arm-smmu-qcom.c | 45 +++++++++++++++++++++++++++++++++--
 drivers/iommu/arm-smmu.h      |  1 +
 3 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
index a20e426d81ac..309675cf6699 100644
--- a/drivers/iommu/arm-smmu-impl.c
+++ b/drivers/iommu/arm-smmu-impl.c
@@ -176,5 +176,8 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
 	    of_device_is_compatible(np, "qcom,sc7180-smmu-500"))
 		return qcom_smmu_impl_init(smmu);
 
+	if (of_device_is_compatible(smmu->dev->of_node, "qcom,adreno-smmu"))
+		return qcom_adreno_smmu_impl_init(smmu);
+
 	return smmu;
 }
diff --git a/drivers/iommu/arm-smmu-qcom.c b/drivers/iommu/arm-smmu-qcom.c
index cf01d0215a39..6d0ab4865fc7 100644
--- a/drivers/iommu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm-smmu-qcom.c
@@ -12,6 +12,29 @@ struct qcom_smmu {
 	struct arm_smmu_device smmu;
 };
 
+static bool qcom_adreno_smmu_is_gpu_device(struct arm_smmu_domain *smmu_domain)
+{
+	return of_device_is_compatible(smmu_domain->dev.of_node, "qcom,adreno");
+}
+
+static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
+		struct io_pgtable_cfg *pgtbl_cfg)
+{
+	/* TTBR1 is only for the GPU stream ID and not the GMU */
+	if (!qcom_adreno_smmu_is_gpu_device(smmu_domain))
+		return 0;
+	/*
+	 * All targets that use the qcom,adreno-smmu compatible string *should*
+	 * be AARCH64 stage 1 but double check because the arm-smmu code assumes
+	 * that is the case when the TTBR1 quirk is enabled
+	 */
+	if ((smmu_domain->stage == ARM_SMMU_DOMAIN_S1) &&
+	    (smmu_domain->cfg.fmt == ARM_SMMU_CTX_FMT_AARCH64))
+		pgtbl_cfg->quirks |= IO_PGTABLE_QUIRK_ARM_TTBR1;
+
+	return 0;
+}
+
 static const struct of_device_id qcom_smmu_client_of_match[] = {
 	{ .compatible = "qcom,adreno" },
 	{ .compatible = "qcom,mdp4" },
@@ -65,7 +88,15 @@ static const struct arm_smmu_impl qcom_smmu_impl = {
 	.reset = qcom_smmu500_reset,
 };
 
-struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
+static const struct arm_smmu_impl qcom_adreno_smmu_impl = {
+	.init_context = qcom_adreno_smmu_init_context,
+	.def_domain_type = qcom_smmu_def_domain_type,
+	.reset = qcom_smmu500_reset,
+};
+
+
+static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
+		const struct arm_smmu_impl *impl)
 {
 	struct qcom_smmu *qsmmu;
 
@@ -75,8 +106,18 @@ struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
 
 	qsmmu->smmu = *smmu;
 
-	qsmmu->smmu.impl = &qcom_smmu_impl;
+	qsmmu->smmu.impl = impl;
 	devm_kfree(smmu->dev, smmu);
 
 	return &qsmmu->smmu;
 }
+
+struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
+{
+	return qcom_smmu_create(smmu, &qcom_smmu_impl);
+}
+
+struct arm_smmu_device *qcom_adreno_smmu_impl_init(struct arm_smmu_device *smmu)
+{
+	return qcom_smmu_create(smmu, &qcom_adreno_smmu_impl);
+}
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index d33cfe26b2f5..c417814f1d98 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -466,6 +466,7 @@ static inline void arm_smmu_writeq(struct arm_smmu_device *smmu, int page,
 
 struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu);
 struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu);
+struct arm_smmu_device *qcom_adreno_smmu_impl_init(struct arm_smmu_device *smmu);
 
 int arm_mmu500_reset(struct arm_smmu_device *smmu);
 
-- 
2.17.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 6/7] drm/msm: Set the global virtual address range from the IOMMU domain
  2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
                   ` (4 preceding siblings ...)
  2020-06-11 22:21 ` [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
  2020-06-12  4:49   ` kernel test robot
  2020-06-11 22:21 ` [PATCH v8 7/7] arm: dts: qcom: sm845: Set the compatible string for the GPU SMMU Jordan Crouse
  6 siblings, 1 reply; 13+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: Jeffrey Hugo, David Airlie, Sean Paul, Douglas Anderson,
	dri-devel, Bjorn Andersson, iommu, Daniel Vetter,
	Thomas Gleixner, Shawn Guo, freedreno, linux-kernel,
	Brian Masney

Use the aperture settings from the IOMMU domain to set up the virtual
address range for the GPU. This allows us to transparently deal with
IOMMU side features (like split pagetables).

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---

 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 13 +++++++++++--
 drivers/gpu/drm/msm/msm_iommu.c         |  7 +++++++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 89673c7ed473..3e717c1ebb7f 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -192,9 +192,18 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu,
 	struct iommu_domain *iommu = iommu_domain_alloc(&platform_bus_type);
 	struct msm_mmu *mmu = msm_iommu_new(&pdev->dev, iommu);
 	struct msm_gem_address_space *aspace;
+	u64 start, size;
 
-	aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
-		0xfffffff);
+	/*
+	 * Use the aperture start or SZ_16M, whichever is greater. This will
+	 * ensure that we align with the allocated pagetable range while still
+	 * allowing room in the lower 32 bits for GMEM and whatnot
+	 */
+	start = max_t(u64, SZ_16M, iommu->geometry.aperture_start);
+	size = iommu->geometry.aperture_end - start + 1;
+
+	aspace = msm_gem_address_space_create(mmu, "gpu",
+		start & GENMASK(48, 0), size);
 
 	if (IS_ERR(aspace) && !IS_ERR(mmu))
 		mmu->funcs->destroy(mmu);
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 3a381a9674c9..bbe129867590 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -36,6 +36,10 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
 	struct msm_iommu *iommu = to_msm_iommu(mmu);
 	size_t ret;
 
+	/* The arm-smmu driver expects the addresses to be sign extended */
+	if (iova & BIT(48))
+		iova |= GENMASK(63, 49);
+
 	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
 	WARN_ON(!ret);
 
@@ -46,6 +50,9 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, size_t len)
 {
 	struct msm_iommu *iommu = to_msm_iommu(mmu);
 
+	if (iova & BIT(48))
+		iova |= GENMASK(63, 49);
+
 	iommu_unmap(iommu->domain, iova, len);
 
 	return 0;
-- 
2.17.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 7/7] arm: dts: qcom: sm845: Set the compatible string for the GPU SMMU
  2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
                   ` (5 preceding siblings ...)
  2020-06-11 22:21 ` [PATCH v8 6/7] drm/msm: Set the global virtual address range from the IOMMU domain Jordan Crouse
@ 2020-06-11 22:21 ` Jordan Crouse
  6 siblings, 0 replies; 13+ messages in thread
From: Jordan Crouse @ 2020-06-11 22:21 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: devicetree, linux-kernel, Rob Herring, Bjorn Andersson, iommu,
	Andy Gross, freedreno

Set the qcom,adreno-smmu compatible string for the GPU SMMU to enable
split pagetables.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
---

 arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 8eb5a31346d2..8b15cd74e9ba 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -3556,7 +3556,7 @@
 		};
 
 		adreno_smmu: iommu@5040000 {
-			compatible = "qcom,sdm845-smmu-v2", "qcom,smmu-v2";
+			compatible = "qcom,adreno-smmu", "qcom,smmu-v2";
 			reg = <0 0x5040000 0 0x10000>;
 			#iommu-cells = <1>;
 			#global-interrupts = <2>;
-- 
2.17.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 4/7] iommu/arm-smmu: Add a pointer to the attached device to smmu_domain
  2020-06-11 22:21 ` [PATCH v8 4/7] iommu/arm-smmu: Add a pointer to the attached device to smmu_domain Jordan Crouse
@ 2020-06-12  4:19   ` kernel test robot
  0 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2020-06-12  4:19 UTC (permalink / raw)
  To: Jordan Crouse, linux-arm-msm
  Cc: kbuild-all, Will Deacon, Robin Murphy, linux-kernel, iommu,
	freedreno, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 9293 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.7 next-20200611]
[cannot apply to iommu/next robh/for-next arm/for-next keystone/next rockchip/for-next arm64/for-next/core shawnguo/for-next soc/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Crouse/iommu-arm-smmu-Enable-split-pagetable-support/20200612-094718
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git b961f8dc8976c091180839f4483d67b7c2ca2578
config: arm64-randconfig-s031-20200612 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.1-250-g42323db3-dirty
        # save the attached .config to linux build tree
        make W=1 C=1 ARCH=arm64 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>, old ones prefixed by <<):

drivers/iommu/arm-smmu.c: In function 'arm_smmu_init_domain_context':
>> drivers/iommu/arm-smmu.c:804:21: error: 'dev' undeclared (first use in this function); did you mean 'cdev'?
804 |  smmu_domain->dev = dev;
|                     ^~~
|                     cdev
drivers/iommu/arm-smmu.c:804:21: note: each undeclared identifier is reported only once for each function it appears in

vim +804 drivers/iommu/arm-smmu.c

   669	
   670	static int arm_smmu_init_domain_context(struct iommu_domain *domain,
   671						struct arm_smmu_device *smmu)
   672	{
   673		int irq, start, ret = 0;
   674		unsigned long ias, oas;
   675		struct io_pgtable_ops *pgtbl_ops;
   676		struct io_pgtable_cfg pgtbl_cfg;
   677		enum io_pgtable_fmt fmt;
   678		struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
   679		struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
   680	
   681		mutex_lock(&smmu_domain->init_mutex);
   682		if (smmu_domain->smmu)
   683			goto out_unlock;
   684	
   685		if (domain->type == IOMMU_DOMAIN_IDENTITY) {
   686			smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
   687			smmu_domain->smmu = smmu;
   688			goto out_unlock;
   689		}
   690	
   691		/*
   692		 * Mapping the requested stage onto what we support is surprisingly
   693		 * complicated, mainly because the spec allows S1+S2 SMMUs without
   694		 * support for nested translation. That means we end up with the
   695		 * following table:
   696		 *
   697		 * Requested        Supported        Actual
   698		 *     S1               N              S1
   699		 *     S1             S1+S2            S1
   700		 *     S1               S2             S2
   701		 *     S1               S1             S1
   702		 *     N                N              N
   703		 *     N              S1+S2            S2
   704		 *     N                S2             S2
   705		 *     N                S1             S1
   706		 *
   707		 * Note that you can't actually request stage-2 mappings.
   708		 */
   709		if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1))
   710			smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
   711		if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
   712			smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
   713	
   714		/*
   715		 * Choosing a suitable context format is even more fiddly. Until we
   716		 * grow some way for the caller to express a preference, and/or move
   717		 * the decision into the io-pgtable code where it arguably belongs,
   718		 * just aim for the closest thing to the rest of the system, and hope
   719		 * that the hardware isn't esoteric enough that we can't assume AArch64
   720		 * support to be a superset of AArch32 support...
   721		 */
   722		if (smmu->features & ARM_SMMU_FEAT_FMT_AARCH32_L)
   723			cfg->fmt = ARM_SMMU_CTX_FMT_AARCH32_L;
   724		if (IS_ENABLED(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) &&
   725		    !IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_ARM_LPAE) &&
   726		    (smmu->features & ARM_SMMU_FEAT_FMT_AARCH32_S) &&
   727		    (smmu_domain->stage == ARM_SMMU_DOMAIN_S1))
   728			cfg->fmt = ARM_SMMU_CTX_FMT_AARCH32_S;
   729		if ((IS_ENABLED(CONFIG_64BIT) || cfg->fmt == ARM_SMMU_CTX_FMT_NONE) &&
   730		    (smmu->features & (ARM_SMMU_FEAT_FMT_AARCH64_64K |
   731				       ARM_SMMU_FEAT_FMT_AARCH64_16K |
   732				       ARM_SMMU_FEAT_FMT_AARCH64_4K)))
   733			cfg->fmt = ARM_SMMU_CTX_FMT_AARCH64;
   734	
   735		if (cfg->fmt == ARM_SMMU_CTX_FMT_NONE) {
   736			ret = -EINVAL;
   737			goto out_unlock;
   738		}
   739	
   740		switch (smmu_domain->stage) {
   741		case ARM_SMMU_DOMAIN_S1:
   742			cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS;
   743			start = smmu->num_s2_context_banks;
   744			ias = smmu->va_size;
   745			oas = smmu->ipa_size;
   746			if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64) {
   747				fmt = ARM_64_LPAE_S1;
   748			} else if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_L) {
   749				fmt = ARM_32_LPAE_S1;
   750				ias = min(ias, 32UL);
   751				oas = min(oas, 40UL);
   752			} else {
   753				fmt = ARM_V7S;
   754				ias = min(ias, 32UL);
   755				oas = min(oas, 32UL);
   756			}
   757			smmu_domain->flush_ops = &arm_smmu_s1_tlb_ops;
   758			break;
   759		case ARM_SMMU_DOMAIN_NESTED:
   760			/*
   761			 * We will likely want to change this if/when KVM gets
   762			 * involved.
   763			 */
   764		case ARM_SMMU_DOMAIN_S2:
   765			cfg->cbar = CBAR_TYPE_S2_TRANS;
   766			start = 0;
   767			ias = smmu->ipa_size;
   768			oas = smmu->pa_size;
   769			if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64) {
   770				fmt = ARM_64_LPAE_S2;
   771			} else {
   772				fmt = ARM_32_LPAE_S2;
   773				ias = min(ias, 40UL);
   774				oas = min(oas, 40UL);
   775			}
   776			if (smmu->version == ARM_SMMU_V2)
   777				smmu_domain->flush_ops = &arm_smmu_s2_tlb_ops_v2;
   778			else
   779				smmu_domain->flush_ops = &arm_smmu_s2_tlb_ops_v1;
   780			break;
   781		default:
   782			ret = -EINVAL;
   783			goto out_unlock;
   784		}
   785		ret = __arm_smmu_alloc_bitmap(smmu->context_map, start,
   786					      smmu->num_context_banks);
   787		if (ret < 0)
   788			goto out_unlock;
   789	
   790		cfg->cbndx = ret;
   791		if (smmu->version < ARM_SMMU_V2) {
   792			cfg->irptndx = atomic_inc_return(&smmu->irptndx);
   793			cfg->irptndx %= smmu->num_context_irqs;
   794		} else {
   795			cfg->irptndx = cfg->cbndx;
   796		}
   797	
   798		if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2)
   799			cfg->vmid = cfg->cbndx + 1;
   800		else
   801			cfg->asid = cfg->cbndx;
   802	
   803		smmu_domain->smmu = smmu;
 > 804		smmu_domain->dev = dev;
   805	
   806		pgtbl_cfg = (struct io_pgtable_cfg) {
   807			.pgsize_bitmap	= smmu->pgsize_bitmap,
   808			.ias		= ias,
   809			.oas		= oas,
   810			.coherent_walk	= smmu->features & ARM_SMMU_FEAT_COHERENT_WALK,
   811			.tlb		= smmu_domain->flush_ops,
   812			.iommu_dev	= smmu->dev,
   813		};
   814	
   815		if (smmu->impl && smmu->impl->init_context) {
   816			ret = smmu->impl->init_context(smmu_domain, &pgtbl_cfg);
   817			if (ret)
   818				goto out_unlock;
   819		}
   820	
   821		if (smmu_domain->non_strict)
   822			pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
   823	
   824		pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
   825		if (!pgtbl_ops) {
   826			ret = -ENOMEM;
   827			goto out_clear_smmu;
   828		}
   829	
   830		/* Update the domain's page sizes to reflect the page table format */
   831		domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
   832	
   833		if (pgtbl_cfg.quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) {
   834			domain->geometry.aperture_start = ~0UL << ias;
   835			domain->geometry.aperture_end = ~0UL;
   836		} else {
   837			domain->geometry.aperture_end = (1UL << ias) - 1;
   838		}
   839	
   840		domain->geometry.force_aperture = true;
   841	
   842		/* Initialise the context bank with our page table cfg */
   843		arm_smmu_init_context_bank(smmu_domain, &pgtbl_cfg);
   844		arm_smmu_write_context_bank(smmu, cfg->cbndx);
   845	
   846		/*
   847		 * Request context fault interrupt. Do this last to avoid the
   848		 * handler seeing a half-initialised domain state.
   849		 */
   850		irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx];
   851		ret = devm_request_irq(smmu->dev, irq, arm_smmu_context_fault,
   852				       IRQF_SHARED, "arm-smmu-context-fault", domain);
   853		if (ret < 0) {
   854			dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
   855				cfg->irptndx, irq);
   856			cfg->irptndx = ARM_SMMU_INVALID_IRPTNDX;
   857		}
   858	
   859		mutex_unlock(&smmu_domain->init_mutex);
   860	
   861		/* Publish page table ops for map/unmap */
   862		smmu_domain->pgtbl_ops = pgtbl_ops;
   863		return 0;
   864	
   865	out_clear_smmu:
   866		__arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
   867		smmu_domain->smmu = NULL;
   868	out_unlock:
   869		mutex_unlock(&smmu_domain->init_mutex);
   870		return ret;
   871	}
   872	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30307 bytes --]

[-- Attachment #3: Type: text/plain, Size: 156 bytes --]

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 6/7] drm/msm: Set the global virtual address range from the IOMMU domain
  2020-06-11 22:21 ` [PATCH v8 6/7] drm/msm: Set the global virtual address range from the IOMMU domain Jordan Crouse
@ 2020-06-12  4:49   ` kernel test robot
  0 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2020-06-12  4:49 UTC (permalink / raw)
  To: Jordan Crouse, linux-arm-msm
  Cc: kbuild-all, Jeffrey Hugo, David Airlie, freedreno,
	Douglas Anderson, dri-devel, Bjorn Andersson, iommu,
	Thomas Gleixner, Sean Paul

[-- Attachment #1: Type: text/plain, Size: 12326 bytes --]

Hi Jordan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on next-20200611]
[cannot apply to iommu/next robh/for-next arm/for-next keystone/next rockchip/for-next arm64/for-next/core shawnguo/for-next soc/for-next v5.7]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Crouse/iommu-arm-smmu-Enable-split-pagetable-support/20200612-094718
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git b961f8dc8976c091180839f4483d67b7c2ca2578
config: arm-defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>, old ones prefixed by <<):

In file included from include/linux/bitops.h:5,
from include/linux/kernel.h:12,
from include/linux/ascii85.h:11,
from drivers/gpu/drm/msm/adreno/adreno_gpu.c:9:
drivers/gpu/drm/msm/adreno/adreno_gpu.c: In function 'adreno_iommu_create_address_space':
include/linux/bits.h:37:11: warning: right shift count is negative [-Wshift-count-negative]
37 |   (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
|           ^~
include/linux/bits.h:39:31: note: in expansion of macro '__GENMASK'
39 |  (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
|                               ^~~~~~~~~
>> drivers/gpu/drm/msm/adreno/adreno_gpu.c:206:11: note: in expansion of macro 'GENMASK'
206 |   start & GENMASK(48, 0), size);
|           ^~~~~~~
--
In file included from include/linux/bits.h:6,
from include/linux/bitops.h:5,
from include/linux/kernel.h:12,
from drivers/gpu/drm/msm/msm_drv.h:11,
from drivers/gpu/drm/msm/msm_iommu.c:7:
drivers/gpu/drm/msm/msm_iommu.c: In function 'msm_iommu_map':
>> include/vdso/bits.h:7:26: warning: left shift count >= width of type [-Wshift-count-overflow]
7 | #define BIT(nr)   (UL(1) << (nr))
|                          ^~
>> drivers/gpu/drm/msm/msm_iommu.c:40:13: note: in expansion of macro 'BIT'
40 |  if (iova & BIT(48))
|             ^~~
In file included from include/linux/bitops.h:5,
from include/linux/kernel.h:12,
from drivers/gpu/drm/msm/msm_drv.h:11,
from drivers/gpu/drm/msm/msm_iommu.c:7:
>> include/linux/bits.h:36:22: warning: left shift count >= width of type [-Wshift-count-overflow]
36 |  (((~UL(0)) - (UL(1) << (l)) + 1) &          |                      ^~
include/linux/bits.h:39:31: note: in expansion of macro '__GENMASK'
39 |  (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
|                               ^~~~~~~~~
>> drivers/gpu/drm/msm/msm_iommu.c:41:11: note: in expansion of macro 'GENMASK'
41 |   iova |= GENMASK(63, 49);
|           ^~~~~~~
include/linux/bits.h:37:11: warning: right shift count is negative [-Wshift-count-negative]
37 |   (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
|           ^~
include/linux/bits.h:39:31: note: in expansion of macro '__GENMASK'
39 |  (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
|                               ^~~~~~~~~
>> drivers/gpu/drm/msm/msm_iommu.c:41:11: note: in expansion of macro 'GENMASK'
41 |   iova |= GENMASK(63, 49);
|           ^~~~~~~
In file included from include/linux/bits.h:6,
from include/linux/bitops.h:5,
from include/linux/kernel.h:12,
from drivers/gpu/drm/msm/msm_drv.h:11,
from drivers/gpu/drm/msm/msm_iommu.c:7:
drivers/gpu/drm/msm/msm_iommu.c: In function 'msm_iommu_unmap':
>> include/vdso/bits.h:7:26: warning: left shift count >= width of type [-Wshift-count-overflow]
7 | #define BIT(nr)   (UL(1) << (nr))
|                          ^~
drivers/gpu/drm/msm/msm_iommu.c:53:13: note: in expansion of macro 'BIT'
53 |  if (iova & BIT(48))
|             ^~~
In file included from include/linux/bitops.h:5,
from include/linux/kernel.h:12,
from drivers/gpu/drm/msm/msm_drv.h:11,
from drivers/gpu/drm/msm/msm_iommu.c:7:
>> include/linux/bits.h:36:22: warning: left shift count >= width of type [-Wshift-count-overflow]
36 |  (((~UL(0)) - (UL(1) << (l)) + 1) &          |                      ^~
include/linux/bits.h:39:31: note: in expansion of macro '__GENMASK'
39 |  (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
|                               ^~~~~~~~~
drivers/gpu/drm/msm/msm_iommu.c:54:11: note: in expansion of macro 'GENMASK'
54 |   iova |= GENMASK(63, 49);
|           ^~~~~~~
include/linux/bits.h:37:11: warning: right shift count is negative [-Wshift-count-negative]
37 |   (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
|           ^~
include/linux/bits.h:39:31: note: in expansion of macro '__GENMASK'
39 |  (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
|                               ^~~~~~~~~
drivers/gpu/drm/msm/msm_iommu.c:54:11: note: in expansion of macro 'GENMASK'
54 |   iova |= GENMASK(63, 49);
|           ^~~~~~~

vim +/GENMASK +206 drivers/gpu/drm/msm/adreno/adreno_gpu.c

   > 9	#include <linux/ascii85.h>
    10	#include <linux/interconnect.h>
    11	#include <linux/qcom_scm.h>
    12	#include <linux/kernel.h>
    13	#include <linux/of_address.h>
    14	#include <linux/pm_opp.h>
    15	#include <linux/slab.h>
    16	#include <linux/soc/qcom/mdt_loader.h>
    17	#include <soc/qcom/ocmem.h>
    18	#include "adreno_gpu.h"
    19	#include "msm_gem.h"
    20	#include "msm_mmu.h"
    21	
    22	static bool zap_available = true;
    23	
    24	static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname,
    25			u32 pasid)
    26	{
    27		struct device *dev = &gpu->pdev->dev;
    28		const struct firmware *fw;
    29		const char *signed_fwname = NULL;
    30		struct device_node *np, *mem_np;
    31		struct resource r;
    32		phys_addr_t mem_phys;
    33		ssize_t mem_size;
    34		void *mem_region = NULL;
    35		int ret;
    36	
    37		if (!IS_ENABLED(CONFIG_ARCH_QCOM)) {
    38			zap_available = false;
    39			return -EINVAL;
    40		}
    41	
    42		np = of_get_child_by_name(dev->of_node, "zap-shader");
    43		if (!np) {
    44			zap_available = false;
    45			return -ENODEV;
    46		}
    47	
    48		mem_np = of_parse_phandle(np, "memory-region", 0);
    49		of_node_put(np);
    50		if (!mem_np) {
    51			zap_available = false;
    52			return -EINVAL;
    53		}
    54	
    55		ret = of_address_to_resource(mem_np, 0, &r);
    56		of_node_put(mem_np);
    57		if (ret)
    58			return ret;
    59	
    60		mem_phys = r.start;
    61	
    62		/*
    63		 * Check for a firmware-name property.  This is the new scheme
    64		 * to handle firmware that may be signed with device specific
    65		 * keys, allowing us to have a different zap fw path for different
    66		 * devices.
    67		 *
    68		 * If the firmware-name property is found, we bypass the
    69		 * adreno_request_fw() mechanism, because we don't need to handle
    70		 * the /lib/firmware/qcom/... vs /lib/firmware/... case.
    71		 *
    72		 * If the firmware-name property is not found, for backwards
    73		 * compatibility we fall back to the fwname from the gpulist
    74		 * table.
    75		 */
    76		of_property_read_string_index(np, "firmware-name", 0, &signed_fwname);
    77		if (signed_fwname) {
    78			fwname = signed_fwname;
    79			ret = request_firmware_direct(&fw, fwname, gpu->dev->dev);
    80			if (ret)
    81				fw = ERR_PTR(ret);
    82		} else if (fwname) {
    83			/* Request the MDT file from the default location: */
    84			fw = adreno_request_fw(to_adreno_gpu(gpu), fwname);
    85		} else {
    86			/*
    87			 * For new targets, we require the firmware-name property,
    88			 * if a zap-shader is required, rather than falling back
    89			 * to a firmware name specified in gpulist.
    90			 *
    91			 * Because the firmware is signed with a (potentially)
    92			 * device specific key, having the name come from gpulist
    93			 * was a bad idea, and is only provided for backwards
    94			 * compatibility for older targets.
    95			 */
    96			return -ENODEV;
    97		}
    98	
    99		if (IS_ERR(fw)) {
   100			DRM_DEV_ERROR(dev, "Unable to load %s\n", fwname);
   101			return PTR_ERR(fw);
   102		}
   103	
   104		/* Figure out how much memory we need */
   105		mem_size = qcom_mdt_get_size(fw);
   106		if (mem_size < 0) {
   107			ret = mem_size;
   108			goto out;
   109		}
   110	
   111		if (mem_size > resource_size(&r)) {
   112			DRM_DEV_ERROR(dev,
   113				"memory region is too small to load the MDT\n");
   114			ret = -E2BIG;
   115			goto out;
   116		}
   117	
   118		/* Allocate memory for the firmware image */
   119		mem_region = memremap(mem_phys, mem_size,  MEMREMAP_WC);
   120		if (!mem_region) {
   121			ret = -ENOMEM;
   122			goto out;
   123		}
   124	
   125		/*
   126		 * Load the rest of the MDT
   127		 *
   128		 * Note that we could be dealing with two different paths, since
   129		 * with upstream linux-firmware it would be in a qcom/ subdir..
   130		 * adreno_request_fw() handles this, but qcom_mdt_load() does
   131		 * not.  But since we've already gotten through adreno_request_fw()
   132		 * we know which of the two cases it is:
   133		 */
   134		if (signed_fwname || (to_adreno_gpu(gpu)->fwloc == FW_LOCATION_LEGACY)) {
   135			ret = qcom_mdt_load(dev, fw, fwname, pasid,
   136					mem_region, mem_phys, mem_size, NULL);
   137		} else {
   138			char *newname;
   139	
   140			newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname);
   141	
   142			ret = qcom_mdt_load(dev, fw, newname, pasid,
   143					mem_region, mem_phys, mem_size, NULL);
   144			kfree(newname);
   145		}
   146		if (ret)
   147			goto out;
   148	
   149		/* Send the image to the secure world */
   150		ret = qcom_scm_pas_auth_and_reset(pasid);
   151	
   152		/*
   153		 * If the scm call returns -EOPNOTSUPP we assume that this target
   154		 * doesn't need/support the zap shader so quietly fail
   155		 */
   156		if (ret == -EOPNOTSUPP)
   157			zap_available = false;
   158		else if (ret)
   159			DRM_DEV_ERROR(dev, "Unable to authorize the image\n");
   160	
   161	out:
   162		if (mem_region)
   163			memunmap(mem_region);
   164	
   165		release_firmware(fw);
   166	
   167		return ret;
   168	}
   169	
   170	int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid)
   171	{
   172		struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
   173		struct platform_device *pdev = gpu->pdev;
   174	
   175		/* Short cut if we determine the zap shader isn't available/needed */
   176		if (!zap_available)
   177			return -ENODEV;
   178	
   179		/* We need SCM to be able to load the firmware */
   180		if (!qcom_scm_is_available()) {
   181			DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n");
   182			return -EPROBE_DEFER;
   183		}
   184	
   185		return zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw, pasid);
   186	}
   187	
   188	struct msm_gem_address_space *
   189	adreno_iommu_create_address_space(struct msm_gpu *gpu,
   190			struct platform_device *pdev)
   191	{
   192		struct iommu_domain *iommu = iommu_domain_alloc(&platform_bus_type);
   193		struct msm_mmu *mmu = msm_iommu_new(&pdev->dev, iommu);
   194		struct msm_gem_address_space *aspace;
   195		u64 start, size;
   196	
   197		/*
   198		 * Use the aperture start or SZ_16M, whichever is greater. This will
   199		 * ensure that we align with the allocated pagetable range while still
   200		 * allowing room in the lower 32 bits for GMEM and whatnot
   201		 */
   202		start = max_t(u64, SZ_16M, iommu->geometry.aperture_start);
   203		size = iommu->geometry.aperture_end - start + 1;
   204	
   205		aspace = msm_gem_address_space_create(mmu, "gpu",
 > 206			start & GENMASK(48, 0), size);
   207	
   208		if (IS_ERR(aspace) && !IS_ERR(mmu))
   209			mmu->funcs->destroy(mmu);
   210	
   211		return aspace;
   212	}
   213	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 52430 bytes --]

[-- Attachment #3: Type: text/plain, Size: 156 bytes --]

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU
  2020-06-11 22:21 ` [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU Jordan Crouse
@ 2020-06-12  5:11   ` kernel test robot
  2020-06-13  1:34   ` kernel test robot
  1 sibling, 0 replies; 13+ messages in thread
From: kernel test robot @ 2020-06-12  5:11 UTC (permalink / raw)
  To: Jordan Crouse, linux-arm-msm
  Cc: kbuild-all, Will Deacon, Robin Murphy, linux-kernel, iommu,
	freedreno, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 2121 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on next-20200611]
[cannot apply to iommu/next robh/for-next arm/for-next keystone/next rockchip/for-next arm64/for-next/core shawnguo/for-next soc/for-next v5.7]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Crouse/iommu-arm-smmu-Enable-split-pagetable-support/20200612-094718
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git b961f8dc8976c091180839f4483d67b7c2ca2578
config: arm64-randconfig-s031-20200612 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.1-250-g42323db3-dirty
        # save the attached .config to linux build tree
        make W=1 C=1 ARCH=arm64 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>, old ones prefixed by <<):

drivers/iommu/arm-smmu-qcom.c: In function 'qcom_adreno_smmu_is_gpu_device':
>> drivers/iommu/arm-smmu-qcom.c:17:49: error: 'smmu_domain->dev' is a pointer; did you mean to use '->'?
17 |  return of_device_is_compatible(smmu_domain->dev.of_node, "qcom,adreno");
|                                                 ^
|                                                 ->
>> drivers/iommu/arm-smmu-qcom.c:18:1: warning: control reaches end of non-void function [-Wreturn-type]
18 | }
| ^

vim +17 drivers/iommu/arm-smmu-qcom.c

    14	
    15	static bool qcom_adreno_smmu_is_gpu_device(struct arm_smmu_domain *smmu_domain)
    16	{
  > 17		return of_device_is_compatible(smmu_domain->dev.of_node, "qcom,adreno");
  > 18	}
    19	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30307 bytes --]

[-- Attachment #3: Type: text/plain, Size: 156 bytes --]

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU
  2020-06-11 22:21 ` [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU Jordan Crouse
  2020-06-12  5:11   ` kernel test robot
@ 2020-06-13  1:34   ` kernel test robot
  1 sibling, 0 replies; 13+ messages in thread
From: kernel test robot @ 2020-06-13  1:34 UTC (permalink / raw)
  To: Jordan Crouse, linux-arm-msm
  Cc: kbuild-all, Will Deacon, Robin Murphy, linux-kernel,
	clang-built-linux, iommu, freedreno, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 2134 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on next-20200612]
[cannot apply to iommu/next robh/for-next arm/for-next keystone/next rockchip/for-next arm64/for-next/core shawnguo/for-next soc/for-next v5.7]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Crouse/iommu-arm-smmu-Enable-split-pagetable-support/20200612-094718
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git b961f8dc8976c091180839f4483d67b7c2ca2578
config: arm64-randconfig-r026-20200612 (attached as .config)
compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 3b43f006294971b8049d4807110032169780e5b8)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> drivers/iommu/arm-smmu-qcom.c:17:49: error: member reference type 'struct device *' is a pointer; did you mean to use '->'?
return of_device_is_compatible(smmu_domain->dev.of_node, "qcom,adreno");
~~~~~~~~~~~~~~~~^
->
1 error generated.

vim +17 drivers/iommu/arm-smmu-qcom.c

    14	
    15	static bool qcom_adreno_smmu_is_gpu_device(struct arm_smmu_domain *smmu_domain)
    16	{
  > 17		return of_device_is_compatible(smmu_domain->dev.of_node, "qcom,adreno");
    18	}
    19	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 43304 bytes --]

[-- Attachment #3: Type: text/plain, Size: 156 bytes --]

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 3/7] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU
  2020-06-11 22:21 ` [PATCH v8 3/7] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU Jordan Crouse
@ 2020-06-17 22:40   ` Rob Herring
  0 siblings, 0 replies; 13+ messages in thread
From: Rob Herring @ 2020-06-17 22:40 UTC (permalink / raw)
  To: Jordan Crouse
  Cc: freedreno, Will Deacon, devicetree, linux-arm-msm, linux-kernel,
	iommu, Rob Herring, Robin Murphy, linux-arm-kernel

On Thu, 11 Jun 2020 16:21:24 -0600, Jordan Crouse wrote:
> Every Qcom Adreno GPU has an embedded SMMU for its own use. These
> devices depend on unique features such as split pagetables,
> different stall/halt requirements and other settings. Identify them
> with a compatible string so that they can be identified in the
> arm-smmu implementation specific code.
> 
> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
> ---
> 
>  Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2020-06-17 22:40 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-11 22:21 [PATCH v8 0/7] iommu/arm-smmu: Enable split pagetable support Jordan Crouse
2020-06-11 22:21 ` [PATCH v8 1/7] iommu/arm-smmu: Pass io-pgtable config to implementation specific function Jordan Crouse
2020-06-11 22:21 ` [PATCH v8 2/7] iommu/arm-smmu: Add support for split pagetables Jordan Crouse
2020-06-11 22:21 ` [PATCH v8 3/7] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU Jordan Crouse
2020-06-17 22:40   ` Rob Herring
2020-06-11 22:21 ` [PATCH v8 4/7] iommu/arm-smmu: Add a pointer to the attached device to smmu_domain Jordan Crouse
2020-06-12  4:19   ` kernel test robot
2020-06-11 22:21 ` [PATCH v8 5/7] iommu/arm-smmu: Add implementation for the adreno GPU SMMU Jordan Crouse
2020-06-12  5:11   ` kernel test robot
2020-06-13  1:34   ` kernel test robot
2020-06-11 22:21 ` [PATCH v8 6/7] drm/msm: Set the global virtual address range from the IOMMU domain Jordan Crouse
2020-06-12  4:49   ` kernel test robot
2020-06-11 22:21 ` [PATCH v8 7/7] arm: dts: qcom: sm845: Set the compatible string for the GPU SMMU Jordan Crouse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).