Re: [PATCH 4/8] iommu/msm: Look up masters per IOMMU instance

From: Dmitry Baryshkov

Date: Tue Apr 21 2026 - 21:00:13 EST


On Tue, Apr 21, 2026 at 11:45:10AM +0200, Alexandre MINETTE via B4 Relay wrote:
> From: Alexandre MINETTE <contact@xxxxxxxxxxx>
>
> MSM IOMMU stores context descriptors on each IOMMU instance. Looking up
> the descriptor through dev_iommu_priv_get() is not sufficient because a
> device can reference multiple IOMMU provider nodes.
>
> Look up the master from the target IOMMU ctx_list instead, and use the
> same helper when probing and attaching devices. This avoids dereferencing
> a NULL master when an IOMMU already has context entries for another
> device, and keeps separate context descriptors for separate IOMMU
> instances.
>
> This is required to boot APQ8064 boards using multiple IOMMU contexts.

Which cores / devices? Could you please add a (trimmed) backtrace? Also
a Fixes tag would be nice.

>
> Signed-off-by: Alexandre MINETTE <contact@xxxxxxxxxxx>
> ---
> drivers/iommu/msm_iommu.c | 28 ++++++++++++++++------------
> 1 file changed, 16 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
> index 0ad5ff431d5b..9c03878d0d2c 100644
> --- a/drivers/iommu/msm_iommu.c
> +++ b/drivers/iommu/msm_iommu.c
> @@ -357,17 +357,25 @@ static int msm_iommu_domain_config(struct msm_priv *priv)
> return 0;
> }
>
> +static struct msm_iommu_ctx_dev *find_iommu_master(struct msm_iommu_dev *iommu,
> + struct device *dev)
> +{
> + struct msm_iommu_ctx_dev *master;
> +
> + list_for_each_entry(master, &iommu->ctx_list, list)
> + if (master->of_node == dev->of_node)
> + return master;
> +
> + return NULL;
> +}
> +
> /* Must be called under msm_iommu_lock */
> static struct msm_iommu_dev *find_iommu_for_dev(struct device *dev)
> {
> struct msm_iommu_dev *iommu, *ret = NULL;
> - struct msm_iommu_ctx_dev *master;
>
> list_for_each_entry(iommu, &qcom_iommu_devices, dev_node) {
> - master = list_first_entry(&iommu->ctx_list,
> - struct msm_iommu_ctx_dev,
> - list);
> - if (master->of_node == dev->of_node) {
> + if (find_iommu_master(iommu, dev)) {
> ret = iommu;
> break;
> }
> @@ -405,10 +413,7 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev,
>
> spin_lock_irqsave(&msm_iommu_lock, flags);
> list_for_each_entry(iommu, &qcom_iommu_devices, dev_node) {
> - master = list_first_entry(&iommu->ctx_list,
> - struct msm_iommu_ctx_dev,
> - list);
> - if (master->of_node == dev->of_node) {
> + if (find_iommu_master(iommu, dev)) {
> ret = __enable_clocks(iommu);
> if (ret)
> goto fail;
> @@ -601,10 +606,10 @@ static int insert_iommu_master(struct device *dev,
> struct msm_iommu_dev **iommu,
> const struct of_phandle_args *spec)
> {
> - struct msm_iommu_ctx_dev *master = dev_iommu_priv_get(dev);
> + struct msm_iommu_ctx_dev *master = find_iommu_master(*iommu, dev);
> int sid;
>
> - if (list_empty(&(*iommu)->ctx_list)) {
> + if (!master) {
> master = kzalloc_obj(*master, GFP_ATOMIC);
> if (!master) {
> dev_err(dev, "Failed to allocate iommu_master\n");
> @@ -612,7 +617,6 @@ static int insert_iommu_master(struct device *dev,
> }
> master->of_node = dev->of_node;
> list_add(&master->list, &(*iommu)->ctx_list);
> - dev_iommu_priv_set(dev, master);
> }
>
> for (sid = 0; sid < master->num_mids; sid++)
>
> --
> 2.43.0
>
>

--
With best wishes
Dmitry