On 7.03.2023 17:44, Dmitry Baryshkov wrote: > On 15/11/2022 12:11, 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-num": when found, the ASID will be forced >> as read from the devicetree. >> >> When "qcom,ctx-num" 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@xxxxxxxxxxxxxx> >> [Marijn: Rebased over next-20221111] >> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@xxxxxxxxxxxxx> >> --- >> 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 bfd7b51eb5db..491a8093f3d6 100644 >> --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c >> +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c >> @@ -551,7 +551,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)) { > > Separate change in my opinion. Please split it to a separate patch with proper Fixes: tag. > >> put_device(&iommu_pdev->dev); >> return -EINVAL; >> } >> @@ -638,7 +639,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: >> @@ -646,7 +648,17 @@ static int get_asid(const struct device_node *np) >> if (of_property_read_u32_index(np, "reg", 0, ®)) Use platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = res->start or something like this, the current approach relies on #address-cells = <1> Konrad >> 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-num", &val)) >> + asid = reg / 0x1000; >> + else >> + asid = val; > > As a matter of preference (and logic) I'd have written that as: > > if (!of_property_read(np, "qcom,ctx-num", &val)) > asid = val; > else > asid = reg / 0x1000; > > LGTM otherwise > >> + >> + return asid; >> } >> static int qcom_iommu_ctx_probe(struct platform_device *pdev) >