diff mbox series

[8/8] iommu/arm-smmu-qcom: Add stream_mapping_reset detail to QCOM SMMUv2

Message ID 20200926130004.13528-9-kholk11@gmail.com (mailing list archive)
State New, archived
Headers show
Series Implement firmware quirks for Qualcomm ARM-SMMUv2 | expand

Commit Message

AngeloGioacchino Del Regno Sept. 26, 2020, 1 p.m. UTC
From: AngeloGioacchino Del Regno <kholk11@gmail.com>

On some Qualcomm SoCs with certain hypervisor configurations,
some context banks are hyp-protected and cannot be disabled,
nor the relative S2CRs can be set as bypass, or a hyp-fault
will be triggered and the system will hang.

This is seen on at least Qualcomm SDM630, SDM636 and SDM660.

Signed-off-by: AngeloGioacchino Del Regno <kholk11@gmail.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

Comments

Bjorn Andersson Oct. 14, 2020, 10:14 p.m. UTC | #1
On Sat 26 Sep 08:00 CDT 2020, kholk11@gmail.com wrote:

> From: AngeloGioacchino Del Regno <kholk11@gmail.com>
> 
> On some Qualcomm SoCs with certain hypervisor configurations,
> some context banks are hyp-protected and cannot be disabled,
> nor the relative S2CRs can be set as bypass, or a hyp-fault
> will be triggered and the system will hang.
> 
> This is seen on at least Qualcomm SDM630, SDM636 and SDM660.
> 
> Signed-off-by: AngeloGioacchino Del Regno <kholk11@gmail.com>
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index b18e70bddf29..364908cc2adf 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -85,6 +85,18 @@ static int qcom_smmuv2_cfg_probe(struct arm_smmu_device *smmu)
>  	return 0;
>  }
>  
> +static void qcom_smmuv2_stream_mapping_reset(struct arm_smmu_device *smmu)
> +{
> +	/*
> +	 * Broken firmware quirk:
> +	 * On some Qualcomm SoCs with certain hypervisor configurations,
> +	 * some context banks are hyp-protected and cannot be disabled,

Wouldn't you run into the same problem when init_domain_context() later
comes along and "accidentally" pick one of these context banks?

Do we have any way of knowing which banks this is, so we can mark them
as busy?

> +	 * nor the relative S2CRs can be set as bypass, or a hyp-fault

On platforms such as SDM845, SM8150, SM8250 etc, writing S2CR of type
BYPASS is trapped by the hypervisor and FAULT is actually written to the
hardware - resulting in a system reset when the associated hardware
tries to perform a memory access.


Is it the actual S2CR write that causes the problem you're seeing or the
fact that it happens to be that you shoot down the display stream as
soon as you touch these registers?

Regards,
Bjorn

> +	 * will be triggered and the system will hang.
> +	 */
> +	return;
> +}
> +
>  static void qcom_smmuv2_test_smr_masks(struct arm_smmu_device *smmu)
>  {
>  	/*
> @@ -99,6 +111,7 @@ static void qcom_smmuv2_test_smr_masks(struct arm_smmu_device *smmu)
>  
>  static const struct arm_smmu_impl qcom_smmuv2_impl = {
>  	.cfg_probe = qcom_smmuv2_cfg_probe,
> +	.stream_mapping_reset = qcom_smmuv2_stream_mapping_reset,
>  	.test_smr_masks = qcom_smmuv2_test_smr_masks,
>  };
>  
> -- 
> 2.28.0
>
diff mbox series

Patch

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index b18e70bddf29..364908cc2adf 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -85,6 +85,18 @@  static int qcom_smmuv2_cfg_probe(struct arm_smmu_device *smmu)
 	return 0;
 }
 
+static void qcom_smmuv2_stream_mapping_reset(struct arm_smmu_device *smmu)
+{
+	/*
+	 * Broken firmware quirk:
+	 * On some Qualcomm SoCs with certain hypervisor configurations,
+	 * some context banks are hyp-protected and cannot be disabled,
+	 * nor the relative S2CRs can be set as bypass, or a hyp-fault
+	 * will be triggered and the system will hang.
+	 */
+	return;
+}
+
 static void qcom_smmuv2_test_smr_masks(struct arm_smmu_device *smmu)
 {
 	/*
@@ -99,6 +111,7 @@  static void qcom_smmuv2_test_smr_masks(struct arm_smmu_device *smmu)
 
 static const struct arm_smmu_impl qcom_smmuv2_impl = {
 	.cfg_probe = qcom_smmuv2_cfg_probe,
+	.stream_mapping_reset = qcom_smmuv2_stream_mapping_reset,
 	.test_smr_masks = qcom_smmuv2_test_smr_masks,
 };