linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2
@ 2023-06-22  9:27 AngeloGioacchino Del Regno
  2023-06-22  9:27 ` [PATCH v5 1/6] dt-bindings: iommu: qcom,iommu: Add qcom,ctx-asid property AngeloGioacchino Del Regno
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-06-22  9:27 UTC (permalink / raw)
  To: agross
  Cc: andersson, luca, konrad.dybcio, dmitry.baryshkov, joro, will,
	robin.murphy, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	robdclark, linux-arm-msm, iommu, devicetree, linux-kernel,
	linux-arm-kernel, AngeloGioacchino Del Regno, kernel

This series adds support for handling "v2" firmware's IOMMU, found
on at least MSM8956 and MSM8976 (some other SoCs also need the same
but I honestly don't remember which ones precisely).

This is strictly required to get functional IOMMUs on these SoCs.

I'm sorry for not performing a much needed schema conversion on
qcom,iommu.txt, but I really didn't have time to do that :-(

This series was tested on Sony Xperia X and X Compact (MSM8956):
ADSP, LPASS, Venus, MSS, MDP and GPU are happy :-)

Changes in v5:
 - Renamed "qcom,ctx-num" to "qcom,ctx-asid" as suggested
   by Rob Herring

Changes in v4:
 - Rebase over next-20230619
 - Rewrite qcom,iommu.txt changes to qcom,iommu.yaml
 - Changed reset writes to only disable CB through CB_SCTLR
   and reset CB_FSR and CB_FAR
 - Addressed misc reviewer's comments

Changes in v3:
 - Removed useless FSRRESTORE reset and definition as pointed
   out in Robin Murphy's review
 - Fixed qcom,iommu.txt changes: squashed MSM8976 compatible
   string addition with msm-iommu-v2 generics addition

Changes in v2:
 - Added back Marijn's notes (sorry man!)
 - Added ARM_SMMU_CB_FSRRESTORE definition
 - Changed context bank reset to properly set FSR and FSRRESTORE

AngeloGioacchino Del Regno (6):
  dt-bindings: iommu: qcom,iommu: Add qcom,ctx-asid property
  iommu/qcom: Use the asid read from device-tree if specified
  iommu/qcom: Disable and reset context bank before programming
  iommu/qcom: Index contexts by asid number to allow asid 0
  dt-bindings: iommu: qcom,iommu: Add QSMMUv2 and MSM8976 compatibles
  iommu/qcom: Add support for QSMMUv2 and QSMMU-500 secured contexts

 .../devicetree/bindings/iommu/qcom,iommu.yaml | 22 +++++--
 drivers/iommu/arm/arm-smmu/qcom_iommu.c       | 62 ++++++++++++++-----
 2 files changed, 64 insertions(+), 20 deletions(-)

-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 1/6] dt-bindings: iommu: qcom,iommu: Add qcom,ctx-asid property
  2023-06-22  9:27 [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2 AngeloGioacchino Del Regno
@ 2023-06-22  9:27 ` AngeloGioacchino Del Regno
  2023-06-22 14:52   ` Rob Herring
  2023-06-22  9:27 ` [PATCH v5 2/6] iommu/qcom: Use the asid read from device-tree if specified AngeloGioacchino Del Regno
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-06-22  9:27 UTC (permalink / raw)
  To: agross
  Cc: andersson, luca, konrad.dybcio, dmitry.baryshkov, joro, will,
	robin.murphy, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	robdclark, linux-arm-msm, iommu, devicetree, linux-kernel,
	linux-arm-kernel, AngeloGioacchino Del Regno, kernel

Add a new "qcom,ctx-asid" property to force an ASID number on IOMMU
contexts where required.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 Documentation/devicetree/bindings/iommu/qcom,iommu.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/qcom,iommu.yaml b/Documentation/devicetree/bindings/iommu/qcom,iommu.yaml
index d9fabdf930d9..f7a64ad8a005 100644
--- a/Documentation/devicetree/bindings/iommu/qcom,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/qcom,iommu.yaml
@@ -71,6 +71,11 @@ patternProperties:
       reg:
         maxItems: 1
 
+      qcom,ctx-asid:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description:
+          The ASID number associated to the context bank.
+
     required:
       - compatible
       - interrupts
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 2/6] iommu/qcom: Use the asid read from device-tree if specified
  2023-06-22  9:27 [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2 AngeloGioacchino Del Regno
  2023-06-22  9:27 ` [PATCH v5 1/6] dt-bindings: iommu: qcom,iommu: Add qcom,ctx-asid property AngeloGioacchino Del Regno
@ 2023-06-22  9:27 ` AngeloGioacchino Del Regno
  2023-06-22  9:31   ` Konrad Dybcio
  2023-08-01 13:49   ` Will Deacon
  2023-06-22  9:27 ` [PATCH v5 3/6] iommu/qcom: Disable and reset context bank before programming AngeloGioacchino Del Regno
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-06-22  9:27 UTC (permalink / raw)
  To: agross
  Cc: andersson, luca, konrad.dybcio, dmitry.baryshkov, joro, will,
	robin.murphy, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	robdclark, linux-arm-msm, iommu, devicetree, linux-kernel,
	linux-arm-kernel, AngeloGioacchino Del Regno, kernel,
	Marijn Suijten

As specified in this driver, the context banks are 0x1000 apart but
on some SoCs the context number does not necessarily match this
logic, hence we end up using the wrong ASID: keeping in mind that
this IOMMU implementation relies heavily on SCM (TZ) calls, it is
mandatory that we communicate the right context number.

Since this is all about how context banks are mapped in firmware,
which may be board dependent (as a different firmware version may
eventually change the expected context bank numbers), introduce a
new property "qcom,ctx-asid": when found, the ASID will be forced
as read from the devicetree.

When "qcom,ctx-asid" is not found, this driver retains the previous
behavior as to avoid breaking older devicetrees or systems that do
not require forcing ASID numbers.

Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
[Marijn: Rebased over next-20221111]
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index a503ed758ec3..8face57c4180 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -531,7 +531,8 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
 	 * index into qcom_iommu->ctxs:
 	 */
 	if (WARN_ON(asid < 1) ||
-	    WARN_ON(asid > qcom_iommu->num_ctxs)) {
+	    WARN_ON(asid > qcom_iommu->num_ctxs) ||
+	    WARN_ON(qcom_iommu->ctxs[asid - 1] == NULL)) {
 		put_device(&iommu_pdev->dev);
 		return -EINVAL;
 	}
@@ -617,7 +618,8 @@ static int qcom_iommu_sec_ptbl_init(struct device *dev)
 
 static int get_asid(const struct device_node *np)
 {
-	u32 reg;
+	u32 reg, val;
+	int asid;
 
 	/* read the "reg" property directly to get the relative address
 	 * of the context bank, and calculate the asid from that:
@@ -625,7 +627,17 @@ static int get_asid(const struct device_node *np)
 	if (of_property_read_u32_index(np, "reg", 0, &reg))
 		return -ENODEV;
 
-	return reg / 0x1000;      /* context banks are 0x1000 apart */
+	/*
+	 * Context banks are 0x1000 apart but, in some cases, the ASID
+	 * number doesn't match to this logic and needs to be passed
+	 * from the DT configuration explicitly.
+	 */
+	if (!of_property_read_u32(np, "qcom,ctx-asid", &val))
+		asid = val;
+	else
+		asid = reg / 0x1000;
+
+	return asid;
 }
 
 static int qcom_iommu_ctx_probe(struct platform_device *pdev)
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 3/6] iommu/qcom: Disable and reset context bank before programming
  2023-06-22  9:27 [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2 AngeloGioacchino Del Regno
  2023-06-22  9:27 ` [PATCH v5 1/6] dt-bindings: iommu: qcom,iommu: Add qcom,ctx-asid property AngeloGioacchino Del Regno
  2023-06-22  9:27 ` [PATCH v5 2/6] iommu/qcom: Use the asid read from device-tree if specified AngeloGioacchino Del Regno
@ 2023-06-22  9:27 ` AngeloGioacchino Del Regno
  2023-06-22  9:32   ` Konrad Dybcio
  2023-06-22  9:27 ` [PATCH v5 4/6] iommu/qcom: Index contexts by asid number to allow asid 0 AngeloGioacchino Del Regno
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-06-22  9:27 UTC (permalink / raw)
  To: agross
  Cc: andersson, luca, konrad.dybcio, dmitry.baryshkov, joro, will,
	robin.murphy, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	robdclark, linux-arm-msm, iommu, devicetree, linux-kernel,
	linux-arm-kernel, AngeloGioacchino Del Regno, kernel

Writing	the new	TTBRs, TCRs and MAIRs on a previously enabled
context bank may trigger a context fault, resulting in firmware
driven AP resets: change the domain initialization programming
sequence to disable the context bank(s) and to also clear the
related fault address (CB_FAR) and fault status (CB_FSR)
registers before writing new values to TTBR0/1, TCR/TCR2, MAIR0/1.

Fixes: 0ae349a0f33f ("iommu/qcom: Add qcom_iommu")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 8face57c4180..f1bd7c035db8 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -273,6 +273,13 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
 			ctx->secure_init = true;
 		}
 
+		/* Disable context bank before programming */
+		iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0);
+
+		/* Clear context bank fault address fault status registers */
+		iommu_writel(ctx, ARM_SMMU_CB_FAR, 0);
+		iommu_writel(ctx, ARM_SMMU_CB_FSR, ARM_SMMU_FSR_FAULT);
+
 		/* TTBRs */
 		iommu_writeq(ctx, ARM_SMMU_CB_TTBR0,
 				pgtbl_cfg.arm_lpae_s1_cfg.ttbr |
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 4/6] iommu/qcom: Index contexts by asid number to allow asid 0
  2023-06-22  9:27 [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2 AngeloGioacchino Del Regno
                   ` (2 preceding siblings ...)
  2023-06-22  9:27 ` [PATCH v5 3/6] iommu/qcom: Disable and reset context bank before programming AngeloGioacchino Del Regno
@ 2023-06-22  9:27 ` AngeloGioacchino Del Regno
  2023-06-22  9:35   ` Konrad Dybcio
  2023-08-01 13:55   ` Will Deacon
  2023-06-22  9:27 ` [PATCH v5 5/6] dt-bindings: iommu: qcom,iommu: Add QSMMUv2 and MSM8976 compatibles AngeloGioacchino Del Regno
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-06-22  9:27 UTC (permalink / raw)
  To: agross
  Cc: andersson, luca, konrad.dybcio, dmitry.baryshkov, joro, will,
	robin.murphy, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	robdclark, linux-arm-msm, iommu, devicetree, linux-kernel,
	linux-arm-kernel, AngeloGioacchino Del Regno, kernel

This driver was indexing the contexts by asid-1, which is probably
done under the assumption that the first ASID is always 1.
Unfortunately this is not always true: at least for MSM8956 and
MSM8976's GPU IOMMU, the gpu_user context's ASID number is zero.
To allow using a zero asid number, index the contexts by `asid`
instead of by `asid - 1`.

While at it, also enhance human readability by renaming the
`num_ctxs` member of struct qcom_iommu_dev to `max_asid`.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index f1bd7c035db8..9786fd094e7d 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -51,8 +51,8 @@ struct qcom_iommu_dev {
 	struct clk_bulk_data clks[CLK_NUM];
 	void __iomem		*local_base;
 	u32			 sec_id;
-	u8			 num_ctxs;
-	struct qcom_iommu_ctx	*ctxs[];   /* indexed by asid-1 */
+	u8			 max_asid;
+	struct qcom_iommu_ctx	*ctxs[];   /* indexed by asid */
 };
 
 struct qcom_iommu_ctx {
@@ -94,7 +94,7 @@ static struct qcom_iommu_ctx * to_ctx(struct qcom_iommu_domain *d, unsigned asid
 	struct qcom_iommu_dev *qcom_iommu = d->iommu;
 	if (!qcom_iommu)
 		return NULL;
-	return qcom_iommu->ctxs[asid - 1];
+	return qcom_iommu->ctxs[asid];
 }
 
 static inline void
@@ -534,12 +534,10 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
 	qcom_iommu = platform_get_drvdata(iommu_pdev);
 
 	/* make sure the asid specified in dt is valid, so we don't have
-	 * to sanity check this elsewhere, since 'asid - 1' is used to
-	 * index into qcom_iommu->ctxs:
+	 * to sanity check this elsewhere:
 	 */
-	if (WARN_ON(asid < 1) ||
-	    WARN_ON(asid > qcom_iommu->num_ctxs) ||
-	    WARN_ON(qcom_iommu->ctxs[asid - 1] == NULL)) {
+	if (WARN_ON(asid > qcom_iommu->max_asid) ||
+	    WARN_ON(qcom_iommu->ctxs[asid] == NULL)) {
 		put_device(&iommu_pdev->dev);
 		return -EINVAL;
 	}
@@ -696,7 +694,7 @@ static int qcom_iommu_ctx_probe(struct platform_device *pdev)
 
 	dev_dbg(dev, "found asid %u\n", ctx->asid);
 
-	qcom_iommu->ctxs[ctx->asid - 1] = ctx;
+	qcom_iommu->ctxs[ctx->asid] = ctx;
 
 	return 0;
 }
@@ -708,7 +706,7 @@ static void qcom_iommu_ctx_remove(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, NULL);
 
-	qcom_iommu->ctxs[ctx->asid - 1] = NULL;
+	qcom_iommu->ctxs[ctx->asid] = NULL;
 }
 
 static const struct of_device_id ctx_of_match[] = {
@@ -755,11 +753,11 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
 	for_each_child_of_node(dev->of_node, child)
 		max_asid = max(max_asid, get_asid(child));
 
-	qcom_iommu = devm_kzalloc(dev, struct_size(qcom_iommu, ctxs, max_asid),
+	qcom_iommu = devm_kzalloc(dev, struct_size(qcom_iommu, ctxs, max_asid + 1),
 				  GFP_KERNEL);
 	if (!qcom_iommu)
 		return -ENOMEM;
-	qcom_iommu->num_ctxs = max_asid;
+	qcom_iommu->max_asid = max_asid;
 	qcom_iommu->dev = dev;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 5/6] dt-bindings: iommu: qcom,iommu: Add QSMMUv2 and MSM8976 compatibles
  2023-06-22  9:27 [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2 AngeloGioacchino Del Regno
                   ` (3 preceding siblings ...)
  2023-06-22  9:27 ` [PATCH v5 4/6] iommu/qcom: Index contexts by asid number to allow asid 0 AngeloGioacchino Del Regno
@ 2023-06-22  9:27 ` AngeloGioacchino Del Regno
  2023-06-22  9:27 ` [PATCH v5 6/6] iommu/qcom: Add support for QSMMUv2 and QSMMU-500 secured contexts AngeloGioacchino Del Regno
  2023-08-11 11:44 ` [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2 Will Deacon
  6 siblings, 0 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-06-22  9:27 UTC (permalink / raw)
  To: agross
  Cc: andersson, luca, konrad.dybcio, dmitry.baryshkov, joro, will,
	robin.murphy, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	robdclark, linux-arm-msm, iommu, devicetree, linux-kernel,
	linux-arm-kernel, AngeloGioacchino Del Regno, kernel, Rob Herring

Add compatible string "qcom,msm-iommu-v2" for the inner node,
along with "qcom,msm8976-iommu" as a first user of it and
"qcom,msm-iommu-v2-ns" and "qcom,msm-iommu-v2-sec" for the context
bank nodes to support Qualcomm's secure fw "SMMU v2" implementation.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/iommu/qcom,iommu.yaml   | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/qcom,iommu.yaml b/Documentation/devicetree/bindings/iommu/qcom,iommu.yaml
index f7a64ad8a005..a74eb899c381 100644
--- a/Documentation/devicetree/bindings/iommu/qcom,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/qcom,iommu.yaml
@@ -17,11 +17,16 @@ description: |
 
 properties:
   compatible:
-    items:
-      - enum:
-          - qcom,msm8916-iommu
-          - qcom,msm8953-iommu
-      - const: qcom,msm-iommu-v1
+    oneOf:
+      - items:
+          - enum:
+              - qcom,msm8916-iommu
+              - qcom,msm8953-iommu
+          - const: qcom,msm-iommu-v1
+      - items:
+          - enum:
+              - qcom,msm8976-iommu
+          - const: qcom,msm-iommu-v2
 
   clocks:
     items:
@@ -64,6 +69,8 @@ patternProperties:
         enum:
           - qcom,msm-iommu-v1-ns
           - qcom,msm-iommu-v1-sec
+          - qcom,msm-iommu-v2-ns
+          - qcom,msm-iommu-v2-sec
 
       interrupts:
         maxItems: 1
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 6/6] iommu/qcom: Add support for QSMMUv2 and QSMMU-500 secured contexts
  2023-06-22  9:27 [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2 AngeloGioacchino Del Regno
                   ` (4 preceding siblings ...)
  2023-06-22  9:27 ` [PATCH v5 5/6] dt-bindings: iommu: qcom,iommu: Add QSMMUv2 and MSM8976 compatibles AngeloGioacchino Del Regno
@ 2023-06-22  9:27 ` AngeloGioacchino Del Regno
  2023-06-22  9:36   ` Konrad Dybcio
  2023-08-11 11:44 ` [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2 Will Deacon
  6 siblings, 1 reply; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-06-22  9:27 UTC (permalink / raw)
  To: agross
  Cc: andersson, luca, konrad.dybcio, dmitry.baryshkov, joro, will,
	robin.murphy, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	robdclark, linux-arm-msm, iommu, devicetree, linux-kernel,
	linux-arm-kernel, AngeloGioacchino Del Regno, kernel,
	Marijn Suijten

On some SoCs like MSM8956, MSM8976 and others, secure contexts are
also secured: these get programmed by the bootloader or TZ (as usual)
but their "interesting" registers are locked out by the hypervisor,
disallowing direct register writes from Linux and, in many cases,
completely disallowing the reprogramming of TTBR, TCR, MAIR and other
registers including, but not limited to, resetting contexts.
This is referred downstream as a "v2" IOMMU but this is effectively
a "v2 firmware configuration" instead.

Luckily, the described behavior of version 2 is effective only on
secure contexts and not on non-secure ones: add support for that,
finally getting a completely working IOMMU on at least MSM8956/76.

Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
[Marijn: Rebased over next-20221111]
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 9786fd094e7d..7b6241f36698 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -59,6 +59,7 @@ struct qcom_iommu_ctx {
 	struct device		*dev;
 	void __iomem		*base;
 	bool			 secure_init;
+	bool			 secured_ctx;
 	u8			 asid;      /* asid and ctx bank # are 1:1 */
 	struct iommu_domain	*domain;
 };
@@ -273,6 +274,12 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
 			ctx->secure_init = true;
 		}
 
+		/* Secured QSMMU-500/QSMMU-v2 contexts cannot be programmed */
+		if (ctx->secured_ctx) {
+			ctx->domain = domain;
+			continue;
+		}
+
 		/* Disable context bank before programming */
 		iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0);
 
@@ -669,10 +676,14 @@ static int qcom_iommu_ctx_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return -ENODEV;
 
+	if (of_device_is_compatible(dev->of_node, "qcom,msm-iommu-v2-sec"))
+		ctx->secured_ctx = true;
+
 	/* clear IRQs before registering fault handler, just in case the
 	 * boot-loader left us a surprise:
 	 */
-	iommu_writel(ctx, ARM_SMMU_CB_FSR, iommu_readl(ctx, ARM_SMMU_CB_FSR));
+	if (!ctx->secured_ctx)
+		iommu_writel(ctx, ARM_SMMU_CB_FSR, iommu_readl(ctx, ARM_SMMU_CB_FSR));
 
 	ret = devm_request_irq(dev, irq,
 			       qcom_iommu_fault,
@@ -712,6 +723,8 @@ static void qcom_iommu_ctx_remove(struct platform_device *pdev)
 static const struct of_device_id ctx_of_match[] = {
 	{ .compatible = "qcom,msm-iommu-v1-ns" },
 	{ .compatible = "qcom,msm-iommu-v1-sec" },
+	{ .compatible = "qcom,msm-iommu-v2-ns" },
+	{ .compatible = "qcom,msm-iommu-v2-sec" },
 	{ /* sentinel */ }
 };
 
@@ -729,7 +742,8 @@ static bool qcom_iommu_has_secure_context(struct qcom_iommu_dev *qcom_iommu)
 	struct device_node *child;
 
 	for_each_child_of_node(qcom_iommu->dev->of_node, child) {
-		if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec")) {
+		if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec") ||
+		    of_device_is_compatible(child, "qcom,msm-iommu-v2-sec")) {
 			of_node_put(child);
 			return true;
 		}
@@ -873,6 +887,7 @@ static const struct dev_pm_ops qcom_iommu_pm_ops = {
 
 static const struct of_device_id qcom_iommu_of_match[] = {
 	{ .compatible = "qcom,msm-iommu-v1" },
+	{ .compatible = "qcom,msm-iommu-v2" },
 	{ /* sentinel */ }
 };
 
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 2/6] iommu/qcom: Use the asid read from device-tree if specified
  2023-06-22  9:27 ` [PATCH v5 2/6] iommu/qcom: Use the asid read from device-tree if specified AngeloGioacchino Del Regno
@ 2023-06-22  9:31   ` Konrad Dybcio
  2023-08-01 13:49   ` Will Deacon
  1 sibling, 0 replies; 16+ messages in thread
From: Konrad Dybcio @ 2023-06-22  9:31 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, agross
  Cc: andersson, luca, dmitry.baryshkov, joro, will, robin.murphy,
	robh+dt, krzysztof.kozlowski+dt, conor+dt, robdclark,
	linux-arm-msm, iommu, devicetree, linux-kernel, linux-arm-kernel,
	kernel, Marijn Suijten

On 22.06.2023 11:27, AngeloGioacchino Del Regno wrote:
> As specified in this driver, the context banks are 0x1000 apart but
> on some SoCs the context number does not necessarily match this
> logic, hence we end up using the wrong ASID: keeping in mind that
> this IOMMU implementation relies heavily on SCM (TZ) calls, it is
> mandatory that we communicate the right context number.
> 
> Since this is all about how context banks are mapped in firmware,
> which may be board dependent (as a different firmware version may
> eventually change the expected context bank numbers), introduce a
> new property "qcom,ctx-asid": when found, the ASID will be forced
> as read from the devicetree.
> 
> When "qcom,ctx-asid" is not found, this driver retains the previous
> behavior as to avoid breaking older devicetrees or systems that do
> not require forcing ASID numbers.
> 
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> [Marijn: Rebased over next-20221111]
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad
>  drivers/iommu/arm/arm-smmu/qcom_iommu.c | 18 +++++++++++++++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> index a503ed758ec3..8face57c4180 100644
> --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> @@ -531,7 +531,8 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
>  	 * index into qcom_iommu->ctxs:
>  	 */
>  	if (WARN_ON(asid < 1) ||
> -	    WARN_ON(asid > qcom_iommu->num_ctxs)) {
> +	    WARN_ON(asid > qcom_iommu->num_ctxs) ||
> +	    WARN_ON(qcom_iommu->ctxs[asid - 1] == NULL)) {
>  		put_device(&iommu_pdev->dev);
>  		return -EINVAL;
>  	}
> @@ -617,7 +618,8 @@ static int qcom_iommu_sec_ptbl_init(struct device *dev)
>  
>  static int get_asid(const struct device_node *np)
>  {
> -	u32 reg;
> +	u32 reg, val;
> +	int asid;
>  
>  	/* read the "reg" property directly to get the relative address
>  	 * of the context bank, and calculate the asid from that:
> @@ -625,7 +627,17 @@ static int get_asid(const struct device_node *np)
>  	if (of_property_read_u32_index(np, "reg", 0, &reg))
>  		return -ENODEV;
>  
> -	return reg / 0x1000;      /* context banks are 0x1000 apart */
> +	/*
> +	 * Context banks are 0x1000 apart but, in some cases, the ASID
> +	 * number doesn't match to this logic and needs to be passed
> +	 * from the DT configuration explicitly.
> +	 */
> +	if (!of_property_read_u32(np, "qcom,ctx-asid", &val))
> +		asid = val;
> +	else
> +		asid = reg / 0x1000;
> +
> +	return asid;
>  }
>  
>  static int qcom_iommu_ctx_probe(struct platform_device *pdev)

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 3/6] iommu/qcom: Disable and reset context bank before programming
  2023-06-22  9:27 ` [PATCH v5 3/6] iommu/qcom: Disable and reset context bank before programming AngeloGioacchino Del Regno
@ 2023-06-22  9:32   ` Konrad Dybcio
  0 siblings, 0 replies; 16+ messages in thread
From: Konrad Dybcio @ 2023-06-22  9:32 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, agross
  Cc: andersson, luca, dmitry.baryshkov, joro, will, robin.murphy,
	robh+dt, krzysztof.kozlowski+dt, conor+dt, robdclark,
	linux-arm-msm, iommu, devicetree, linux-kernel, linux-arm-kernel,
	kernel

On 22.06.2023 11:27, AngeloGioacchino Del Regno wrote:
> Writing	the new	TTBRs, TCRs and MAIRs on a previously enabled
> context bank may trigger a context fault, resulting in firmware
> driven AP resets: change the domain initialization programming
> sequence to disable the context bank(s) and to also clear the
> related fault address (CB_FAR) and fault status (CB_FSR)
> registers before writing new values to TTBR0/1, TCR/TCR2, MAIR0/1.
> 
> Fixes: 0ae349a0f33f ("iommu/qcom: Add qcom_iommu")
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad
>  drivers/iommu/arm/arm-smmu/qcom_iommu.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> index 8face57c4180..f1bd7c035db8 100644
> --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> @@ -273,6 +273,13 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
>  			ctx->secure_init = true;
>  		}
>  
> +		/* Disable context bank before programming */
> +		iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0);
> +
> +		/* Clear context bank fault address fault status registers */
> +		iommu_writel(ctx, ARM_SMMU_CB_FAR, 0);
> +		iommu_writel(ctx, ARM_SMMU_CB_FSR, ARM_SMMU_FSR_FAULT);
> +
>  		/* TTBRs */
>  		iommu_writeq(ctx, ARM_SMMU_CB_TTBR0,
>  				pgtbl_cfg.arm_lpae_s1_cfg.ttbr |

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 4/6] iommu/qcom: Index contexts by asid number to allow asid 0
  2023-06-22  9:27 ` [PATCH v5 4/6] iommu/qcom: Index contexts by asid number to allow asid 0 AngeloGioacchino Del Regno
@ 2023-06-22  9:35   ` Konrad Dybcio
  2023-08-01 13:55   ` Will Deacon
  1 sibling, 0 replies; 16+ messages in thread
From: Konrad Dybcio @ 2023-06-22  9:35 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, agross
  Cc: andersson, luca, dmitry.baryshkov, joro, will, robin.murphy,
	robh+dt, krzysztof.kozlowski+dt, conor+dt, robdclark,
	linux-arm-msm, iommu, devicetree, linux-kernel, linux-arm-kernel,
	kernel

On 22.06.2023 11:27, AngeloGioacchino Del Regno wrote:
> This driver was indexing the contexts by asid-1, which is probably
> done under the assumption that the first ASID is always 1.
> Unfortunately this is not always true: at least for MSM8956 and
> MSM8976's GPU IOMMU, the gpu_user context's ASID number is zero.
> To allow using a zero asid number, index the contexts by `asid`
> instead of by `asid - 1`.
> 
> While at it, also enhance human readability by renaming the
> `num_ctxs` member of struct qcom_iommu_dev to `max_asid`.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad
>  drivers/iommu/arm/arm-smmu/qcom_iommu.c | 22 ++++++++++------------
>  1 file changed, 10 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> index f1bd7c035db8..9786fd094e7d 100644
> --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> @@ -51,8 +51,8 @@ struct qcom_iommu_dev {
>  	struct clk_bulk_data clks[CLK_NUM];
>  	void __iomem		*local_base;
>  	u32			 sec_id;
> -	u8			 num_ctxs;
> -	struct qcom_iommu_ctx	*ctxs[];   /* indexed by asid-1 */
> +	u8			 max_asid;
> +	struct qcom_iommu_ctx	*ctxs[];   /* indexed by asid */
>  };
>  
>  struct qcom_iommu_ctx {
> @@ -94,7 +94,7 @@ static struct qcom_iommu_ctx * to_ctx(struct qcom_iommu_domain *d, unsigned asid
>  	struct qcom_iommu_dev *qcom_iommu = d->iommu;
>  	if (!qcom_iommu)
>  		return NULL;
> -	return qcom_iommu->ctxs[asid - 1];
> +	return qcom_iommu->ctxs[asid];
>  }
>  
>  static inline void
> @@ -534,12 +534,10 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
>  	qcom_iommu = platform_get_drvdata(iommu_pdev);
>  
>  	/* make sure the asid specified in dt is valid, so we don't have
> -	 * to sanity check this elsewhere, since 'asid - 1' is used to
> -	 * index into qcom_iommu->ctxs:
> +	 * to sanity check this elsewhere:
>  	 */
> -	if (WARN_ON(asid < 1) ||
> -	    WARN_ON(asid > qcom_iommu->num_ctxs) ||
> -	    WARN_ON(qcom_iommu->ctxs[asid - 1] == NULL)) {
> +	if (WARN_ON(asid > qcom_iommu->max_asid) ||
> +	    WARN_ON(qcom_iommu->ctxs[asid] == NULL)) {
>  		put_device(&iommu_pdev->dev);
>  		return -EINVAL;
>  	}
> @@ -696,7 +694,7 @@ static int qcom_iommu_ctx_probe(struct platform_device *pdev)
>  
>  	dev_dbg(dev, "found asid %u\n", ctx->asid);
>  
> -	qcom_iommu->ctxs[ctx->asid - 1] = ctx;
> +	qcom_iommu->ctxs[ctx->asid] = ctx;
>  
>  	return 0;
>  }
> @@ -708,7 +706,7 @@ static void qcom_iommu_ctx_remove(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, NULL);
>  
> -	qcom_iommu->ctxs[ctx->asid - 1] = NULL;
> +	qcom_iommu->ctxs[ctx->asid] = NULL;
>  }
>  
>  static const struct of_device_id ctx_of_match[] = {
> @@ -755,11 +753,11 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
>  	for_each_child_of_node(dev->of_node, child)
>  		max_asid = max(max_asid, get_asid(child));
>  
> -	qcom_iommu = devm_kzalloc(dev, struct_size(qcom_iommu, ctxs, max_asid),
> +	qcom_iommu = devm_kzalloc(dev, struct_size(qcom_iommu, ctxs, max_asid + 1),
>  				  GFP_KERNEL);
>  	if (!qcom_iommu)
>  		return -ENOMEM;
> -	qcom_iommu->num_ctxs = max_asid;
> +	qcom_iommu->max_asid = max_asid;
>  	qcom_iommu->dev = dev;
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 6/6] iommu/qcom: Add support for QSMMUv2 and QSMMU-500 secured contexts
  2023-06-22  9:27 ` [PATCH v5 6/6] iommu/qcom: Add support for QSMMUv2 and QSMMU-500 secured contexts AngeloGioacchino Del Regno
@ 2023-06-22  9:36   ` Konrad Dybcio
  0 siblings, 0 replies; 16+ messages in thread
From: Konrad Dybcio @ 2023-06-22  9:36 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, agross
  Cc: andersson, luca, dmitry.baryshkov, joro, will, robin.murphy,
	robh+dt, krzysztof.kozlowski+dt, conor+dt, robdclark,
	linux-arm-msm, iommu, devicetree, linux-kernel, linux-arm-kernel,
	kernel, Marijn Suijten

On 22.06.2023 11:27, AngeloGioacchino Del Regno wrote:
> On some SoCs like MSM8956, MSM8976 and others, secure contexts are
> also secured: these get programmed by the bootloader or TZ (as usual)
> but their "interesting" registers are locked out by the hypervisor,
> disallowing direct register writes from Linux and, in many cases,
> completely disallowing the reprogramming of TTBR, TCR, MAIR and other
> registers including, but not limited to, resetting contexts.
> This is referred downstream as a "v2" IOMMU but this is effectively
> a "v2 firmware configuration" instead.
> 
> Luckily, the described behavior of version 2 is effective only on
> secure contexts and not on non-secure ones: add support for that,
> finally getting a completely working IOMMU on at least MSM8956/76.
> 
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> [Marijn: Rebased over next-20221111]
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad
>  drivers/iommu/arm/arm-smmu/qcom_iommu.c | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> index 9786fd094e7d..7b6241f36698 100644
> --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> @@ -59,6 +59,7 @@ struct qcom_iommu_ctx {
>  	struct device		*dev;
>  	void __iomem		*base;
>  	bool			 secure_init;
> +	bool			 secured_ctx;
>  	u8			 asid;      /* asid and ctx bank # are 1:1 */
>  	struct iommu_domain	*domain;
>  };
> @@ -273,6 +274,12 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
>  			ctx->secure_init = true;
>  		}
>  
> +		/* Secured QSMMU-500/QSMMU-v2 contexts cannot be programmed */
> +		if (ctx->secured_ctx) {
> +			ctx->domain = domain;
> +			continue;
> +		}
> +
>  		/* Disable context bank before programming */
>  		iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0);
>  
> @@ -669,10 +676,14 @@ static int qcom_iommu_ctx_probe(struct platform_device *pdev)
>  	if (irq < 0)
>  		return -ENODEV;
>  
> +	if (of_device_is_compatible(dev->of_node, "qcom,msm-iommu-v2-sec"))
> +		ctx->secured_ctx = true;
> +
>  	/* clear IRQs before registering fault handler, just in case the
>  	 * boot-loader left us a surprise:
>  	 */
> -	iommu_writel(ctx, ARM_SMMU_CB_FSR, iommu_readl(ctx, ARM_SMMU_CB_FSR));
> +	if (!ctx->secured_ctx)
> +		iommu_writel(ctx, ARM_SMMU_CB_FSR, iommu_readl(ctx, ARM_SMMU_CB_FSR));
>  
>  	ret = devm_request_irq(dev, irq,
>  			       qcom_iommu_fault,
> @@ -712,6 +723,8 @@ static void qcom_iommu_ctx_remove(struct platform_device *pdev)
>  static const struct of_device_id ctx_of_match[] = {
>  	{ .compatible = "qcom,msm-iommu-v1-ns" },
>  	{ .compatible = "qcom,msm-iommu-v1-sec" },
> +	{ .compatible = "qcom,msm-iommu-v2-ns" },
> +	{ .compatible = "qcom,msm-iommu-v2-sec" },
>  	{ /* sentinel */ }
>  };
>  
> @@ -729,7 +742,8 @@ static bool qcom_iommu_has_secure_context(struct qcom_iommu_dev *qcom_iommu)
>  	struct device_node *child;
>  
>  	for_each_child_of_node(qcom_iommu->dev->of_node, child) {
> -		if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec")) {
> +		if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec") ||
> +		    of_device_is_compatible(child, "qcom,msm-iommu-v2-sec")) {
>  			of_node_put(child);
>  			return true;
>  		}
> @@ -873,6 +887,7 @@ static const struct dev_pm_ops qcom_iommu_pm_ops = {
>  
>  static const struct of_device_id qcom_iommu_of_match[] = {
>  	{ .compatible = "qcom,msm-iommu-v1" },
> +	{ .compatible = "qcom,msm-iommu-v2" },
>  	{ /* sentinel */ }
>  };
>  

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 1/6] dt-bindings: iommu: qcom,iommu: Add qcom,ctx-asid property
  2023-06-22  9:27 ` [PATCH v5 1/6] dt-bindings: iommu: qcom,iommu: Add qcom,ctx-asid property AngeloGioacchino Del Regno
@ 2023-06-22 14:52   ` Rob Herring
  0 siblings, 0 replies; 16+ messages in thread
From: Rob Herring @ 2023-06-22 14:52 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: andersson, luca, krzysztof.kozlowski+dt, iommu, linux-kernel,
	robin.murphy, linux-arm-kernel, agross, robdclark, linux-arm-msm,
	robh+dt, will, devicetree, kernel, dmitry.baryshkov,
	konrad.dybcio, joro, conor+dt


On Thu, 22 Jun 2023 11:27:37 +0200, AngeloGioacchino Del Regno wrote:
> Add a new "qcom,ctx-asid" property to force an ASID number on IOMMU
> contexts where required.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
>  Documentation/devicetree/bindings/iommu/qcom,iommu.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 2/6] iommu/qcom: Use the asid read from device-tree if specified
  2023-06-22  9:27 ` [PATCH v5 2/6] iommu/qcom: Use the asid read from device-tree if specified AngeloGioacchino Del Regno
  2023-06-22  9:31   ` Konrad Dybcio
@ 2023-08-01 13:49   ` Will Deacon
  2023-08-01 14:02     ` AngeloGioacchino Del Regno
  1 sibling, 1 reply; 16+ messages in thread
From: Will Deacon @ 2023-08-01 13:49 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: agross, andersson, luca, konrad.dybcio, dmitry.baryshkov, joro,
	robin.murphy, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	robdclark, linux-arm-msm, iommu, devicetree, linux-kernel,
	linux-arm-kernel, kernel, Marijn Suijten

On Thu, Jun 22, 2023 at 11:27:38AM +0200, AngeloGioacchino Del Regno wrote:
> As specified in this driver, the context banks are 0x1000 apart but
> on some SoCs the context number does not necessarily match this
> logic, hence we end up using the wrong ASID: keeping in mind that
> this IOMMU implementation relies heavily on SCM (TZ) calls, it is
> mandatory that we communicate the right context number.
> 
> Since this is all about how context banks are mapped in firmware,
> which may be board dependent (as a different firmware version may
> eventually change the expected context bank numbers), introduce a
> new property "qcom,ctx-asid": when found, the ASID will be forced
> as read from the devicetree.
> 
> When "qcom,ctx-asid" is not found, this driver retains the previous
> behavior as to avoid breaking older devicetrees or systems that do
> not require forcing ASID numbers.
> 
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> [Marijn: Rebased over next-20221111]
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
>  drivers/iommu/arm/arm-smmu/qcom_iommu.c | 18 +++++++++++++++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> index a503ed758ec3..8face57c4180 100644
> --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> @@ -531,7 +531,8 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
>  	 * index into qcom_iommu->ctxs:
>  	 */
>  	if (WARN_ON(asid < 1) ||
> -	    WARN_ON(asid > qcom_iommu->num_ctxs)) {
> +	    WARN_ON(asid > qcom_iommu->num_ctxs) ||
> +	    WARN_ON(qcom_iommu->ctxs[asid - 1] == NULL)) {
>  		put_device(&iommu_pdev->dev);
>  		return -EINVAL;
>  	}
> @@ -617,7 +618,8 @@ static int qcom_iommu_sec_ptbl_init(struct device *dev)
>  
>  static int get_asid(const struct device_node *np)
>  {
> -	u32 reg;
> +	u32 reg, val;
> +	int asid;
>  
>  	/* read the "reg" property directly to get the relative address
>  	 * of the context bank, and calculate the asid from that:
> @@ -625,7 +627,17 @@ static int get_asid(const struct device_node *np)
>  	if (of_property_read_u32_index(np, "reg", 0, &reg))
>  		return -ENODEV;
>  
> -	return reg / 0x1000;      /* context banks are 0x1000 apart */
> +	/*
> +	 * Context banks are 0x1000 apart but, in some cases, the ASID
> +	 * number doesn't match to this logic and needs to be passed
> +	 * from the DT configuration explicitly.
> +	 */
> +	if (!of_property_read_u32(np, "qcom,ctx-asid", &val))
> +		asid = val;
> +	else
> +		asid = reg / 0x1000;
> +
> +	return asid;

Shouldn't we at least have some error checking here? For example, ensuring
that the ASIDs are within range, aren't duplicates etc?

Also, can you elaborate a little more on what sort of ASID-to-Context
mappings you actually see in practice?

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 4/6] iommu/qcom: Index contexts by asid number to allow asid 0
  2023-06-22  9:27 ` [PATCH v5 4/6] iommu/qcom: Index contexts by asid number to allow asid 0 AngeloGioacchino Del Regno
  2023-06-22  9:35   ` Konrad Dybcio
@ 2023-08-01 13:55   ` Will Deacon
  1 sibling, 0 replies; 16+ messages in thread
From: Will Deacon @ 2023-08-01 13:55 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: agross, andersson, luca, konrad.dybcio, dmitry.baryshkov, joro,
	robin.murphy, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	robdclark, linux-arm-msm, iommu, devicetree, linux-kernel,
	linux-arm-kernel, kernel

On Thu, Jun 22, 2023 at 11:27:40AM +0200, AngeloGioacchino Del Regno wrote:
> This driver was indexing the contexts by asid-1, which is probably
> done under the assumption that the first ASID is always 1.
> Unfortunately this is not always true: at least for MSM8956 and
> MSM8976's GPU IOMMU, the gpu_user context's ASID number is zero.
> To allow using a zero asid number, index the contexts by `asid`
> instead of by `asid - 1`.
> 
> While at it, also enhance human readability by renaming the
> `num_ctxs` member of struct qcom_iommu_dev to `max_asid`.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
>  drivers/iommu/arm/arm-smmu/qcom_iommu.c | 22 ++++++++++------------
>  1 file changed, 10 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> index f1bd7c035db8..9786fd094e7d 100644
> --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> @@ -51,8 +51,8 @@ struct qcom_iommu_dev {
>  	struct clk_bulk_data clks[CLK_NUM];
>  	void __iomem		*local_base;
>  	u32			 sec_id;
> -	u8			 num_ctxs;
> -	struct qcom_iommu_ctx	*ctxs[];   /* indexed by asid-1 */
> +	u8			 max_asid;
> +	struct qcom_iommu_ctx	*ctxs[];   /* indexed by asid */
>  };
>  
>  struct qcom_iommu_ctx {
> @@ -94,7 +94,7 @@ static struct qcom_iommu_ctx * to_ctx(struct qcom_iommu_domain *d, unsigned asid
>  	struct qcom_iommu_dev *qcom_iommu = d->iommu;
>  	if (!qcom_iommu)
>  		return NULL;
> -	return qcom_iommu->ctxs[asid - 1];
> +	return qcom_iommu->ctxs[asid];
>  }
>  
>  static inline void
> @@ -534,12 +534,10 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
>  	qcom_iommu = platform_get_drvdata(iommu_pdev);
>  
>  	/* make sure the asid specified in dt is valid, so we don't have
> -	 * to sanity check this elsewhere, since 'asid - 1' is used to
> -	 * index into qcom_iommu->ctxs:
> +	 * to sanity check this elsewhere:
>  	 */
> -	if (WARN_ON(asid < 1) ||
> -	    WARN_ON(asid > qcom_iommu->num_ctxs) ||
> -	    WARN_ON(qcom_iommu->ctxs[asid - 1] == NULL)) {
> +	if (WARN_ON(asid > qcom_iommu->max_asid) ||
> +	    WARN_ON(qcom_iommu->ctxs[asid] == NULL)) {
>  		put_device(&iommu_pdev->dev);
>  		return -EINVAL;
>  	}
> @@ -696,7 +694,7 @@ static int qcom_iommu_ctx_probe(struct platform_device *pdev)
>  
>  	dev_dbg(dev, "found asid %u\n", ctx->asid);
>  
> -	qcom_iommu->ctxs[ctx->asid - 1] = ctx;
> +	qcom_iommu->ctxs[ctx->asid] = ctx;
>  
>  	return 0;
>  }
> @@ -708,7 +706,7 @@ static void qcom_iommu_ctx_remove(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, NULL);
>  
> -	qcom_iommu->ctxs[ctx->asid - 1] = NULL;
> +	qcom_iommu->ctxs[ctx->asid] = NULL;
>  }
>  
>  static const struct of_device_id ctx_of_match[] = {
> @@ -755,11 +753,11 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
>  	for_each_child_of_node(dev->of_node, child)
>  		max_asid = max(max_asid, get_asid(child));
>  
> -	qcom_iommu = devm_kzalloc(dev, struct_size(qcom_iommu, ctxs, max_asid),
> +	qcom_iommu = devm_kzalloc(dev, struct_size(qcom_iommu, ctxs, max_asid + 1),
>  				  GFP_KERNEL);

So is this '+ 1' there to handle the case where ASIDs are indexed from 1? If
so, please add a comment because this isn't obvious at all.

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 2/6] iommu/qcom: Use the asid read from device-tree if specified
  2023-08-01 13:49   ` Will Deacon
@ 2023-08-01 14:02     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-08-01 14:02 UTC (permalink / raw)
  To: Will Deacon
  Cc: agross, andersson, luca, konrad.dybcio, dmitry.baryshkov, joro,
	robin.murphy, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	robdclark, linux-arm-msm, iommu, devicetree, linux-kernel,
	linux-arm-kernel, kernel, Marijn Suijten

Il 01/08/23 15:49, Will Deacon ha scritto:
> On Thu, Jun 22, 2023 at 11:27:38AM +0200, AngeloGioacchino Del Regno wrote:
>> As specified in this driver, the context banks are 0x1000 apart but
>> on some SoCs the context number does not necessarily match this
>> logic, hence we end up using the wrong ASID: keeping in mind that
>> this IOMMU implementation relies heavily on SCM (TZ) calls, it is
>> mandatory that we communicate the right context number.
>>
>> Since this is all about how context banks are mapped in firmware,
>> which may be board dependent (as a different firmware version may
>> eventually change the expected context bank numbers), introduce a
>> new property "qcom,ctx-asid": when found, the ASID will be forced
>> as read from the devicetree.
>>
>> When "qcom,ctx-asid" is not found, this driver retains the previous
>> behavior as to avoid breaking older devicetrees or systems that do
>> not require forcing ASID numbers.
>>
>> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
>> [Marijn: Rebased over next-20221111]
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> ---
>>   drivers/iommu/arm/arm-smmu/qcom_iommu.c | 18 +++++++++++++++---
>>   1 file changed, 15 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
>> index a503ed758ec3..8face57c4180 100644
>> --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
>> +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
>> @@ -531,7 +531,8 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
>>   	 * index into qcom_iommu->ctxs:
>>   	 */
>>   	if (WARN_ON(asid < 1) ||
>> -	    WARN_ON(asid > qcom_iommu->num_ctxs)) {
>> +	    WARN_ON(asid > qcom_iommu->num_ctxs) ||
>> +	    WARN_ON(qcom_iommu->ctxs[asid - 1] == NULL)) {
>>   		put_device(&iommu_pdev->dev);
>>   		return -EINVAL;
>>   	}
>> @@ -617,7 +618,8 @@ static int qcom_iommu_sec_ptbl_init(struct device *dev)
>>   
>>   static int get_asid(const struct device_node *np)
>>   {
>> -	u32 reg;
>> +	u32 reg, val;
>> +	int asid;
>>   
>>   	/* read the "reg" property directly to get the relative address
>>   	 * of the context bank, and calculate the asid from that:
>> @@ -625,7 +627,17 @@ static int get_asid(const struct device_node *np)
>>   	if (of_property_read_u32_index(np, "reg", 0, &reg))
>>   		return -ENODEV;
>>   
>> -	return reg / 0x1000;      /* context banks are 0x1000 apart */
>> +	/*
>> +	 * Context banks are 0x1000 apart but, in some cases, the ASID
>> +	 * number doesn't match to this logic and needs to be passed
>> +	 * from the DT configuration explicitly.
>> +	 */
>> +	if (!of_property_read_u32(np, "qcom,ctx-asid", &val))
>> +		asid = val;
>> +	else
>> +		asid = reg / 0x1000;
>> +
>> +	return asid;
> 
> Shouldn't we at least have some error checking here? For example, ensuring
> that the ASIDs are within range, aren't duplicates etc?
> 

The only check that we can perform here for ASID-in-range is

if ((asid * 0x1000 > (mmio_start + mmio_size - 0x1000))
	return -EINVAL;

...as for duplicates, a check can *probably* (surely) be done... but I'm not
sure I have any more time to feed more code to this series from years ago...

> Also, can you elaborate a little more on what sort of ASID-to-Context
> mappings you actually see in practice?
> 

I'm sorry, but not really. The first version of this (including the whole research
that I had to perform to write those patches) is from year 2019, so 4 years ago...

...I don't really remember the full details anymore - if not that all of this was
done because context banks are fixed (and setup by TZ), tz takes an asid number
when trying to perform any operation on the context bank, and there's no way to
reset mappings because everything is protected by the hypervisor (which will fault
and reboot the AP instantly if you try).

Cheers,
Angelo



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2
  2023-06-22  9:27 [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2 AngeloGioacchino Del Regno
                   ` (5 preceding siblings ...)
  2023-06-22  9:27 ` [PATCH v5 6/6] iommu/qcom: Add support for QSMMUv2 and QSMMU-500 secured contexts AngeloGioacchino Del Regno
@ 2023-08-11 11:44 ` Will Deacon
  6 siblings, 0 replies; 16+ messages in thread
From: Will Deacon @ 2023-08-11 11:44 UTC (permalink / raw)
  To: agross, AngeloGioacchino Del Regno
  Cc: catalin.marinas, kernel-team, Will Deacon, krzysztof.kozlowski+dt,
	robh+dt, luca, conor+dt, robin.murphy, robdclark, linux-arm-msm,
	konrad.dybcio, iommu, kernel, andersson, devicetree,
	linux-arm-kernel, joro, linux-kernel, dmitry.baryshkov

On Thu, 22 Jun 2023 11:27:36 +0200, AngeloGioacchino Del Regno wrote:
> This series adds support for handling "v2" firmware's IOMMU, found
> on at least MSM8956 and MSM8976 (some other SoCs also need the same
> but I honestly don't remember which ones precisely).
> 
> This is strictly required to get functional IOMMUs on these SoCs.
> 
> I'm sorry for not performing a much needed schema conversion on
> qcom,iommu.txt, but I really didn't have time to do that :-(
> 
> [...]

Applied drivers updated to will (for-joerg/arm-smmu/updates), thanks!

[2/6] iommu/qcom: Use the asid read from device-tree if specified
      https://git.kernel.org/will/c/fcf226f1f708
[3/6] iommu/qcom: Disable and reset context bank before programming
      https://git.kernel.org/will/c/9f3fef23d9b5
[4/6] iommu/qcom: Index contexts by asid number to allow asid 0
      https://git.kernel.org/will/c/ec5601661bfc
[6/6] iommu/qcom: Add support for QSMMUv2 and QSMMU-500 secured contexts
      https://git.kernel.org/will/c/e30c960d3f44

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2023-08-11 11:45 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-22  9:27 [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2 AngeloGioacchino Del Regno
2023-06-22  9:27 ` [PATCH v5 1/6] dt-bindings: iommu: qcom,iommu: Add qcom,ctx-asid property AngeloGioacchino Del Regno
2023-06-22 14:52   ` Rob Herring
2023-06-22  9:27 ` [PATCH v5 2/6] iommu/qcom: Use the asid read from device-tree if specified AngeloGioacchino Del Regno
2023-06-22  9:31   ` Konrad Dybcio
2023-08-01 13:49   ` Will Deacon
2023-08-01 14:02     ` AngeloGioacchino Del Regno
2023-06-22  9:27 ` [PATCH v5 3/6] iommu/qcom: Disable and reset context bank before programming AngeloGioacchino Del Regno
2023-06-22  9:32   ` Konrad Dybcio
2023-06-22  9:27 ` [PATCH v5 4/6] iommu/qcom: Index contexts by asid number to allow asid 0 AngeloGioacchino Del Regno
2023-06-22  9:35   ` Konrad Dybcio
2023-08-01 13:55   ` Will Deacon
2023-06-22  9:27 ` [PATCH v5 5/6] dt-bindings: iommu: qcom,iommu: Add QSMMUv2 and MSM8976 compatibles AngeloGioacchino Del Regno
2023-06-22  9:27 ` [PATCH v5 6/6] iommu/qcom: Add support for QSMMUv2 and QSMMU-500 secured contexts AngeloGioacchino Del Regno
2023-06-22  9:36   ` Konrad Dybcio
2023-08-11 11:44 ` [PATCH v5 0/6] Add support for Qualcomm's legacy IOMMU v2 Will Deacon

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).