[RFC PATCH] iommu/arm-smmu-v3: Allow nested attach for PCI bridges without vDEVICE

Dmitry Malkin <[email protected]>
Newsgroups gmane.linux.kernel.stable,gmane.linux.ports.arm.kernel,gmane.linux.kernel
Message-ID <PA1P190MB25578C482C8A3B06A4DCC6FDDBDA2@PA1P190MB2557.EURP190.PROD.OUTLOOK.COM>
IOMMU groups can contain passed-through endpoints and host PCI bridges.
QEMU creates vDEVICEs for the endpoints, but not for bridges that are
not visible to the guest.

Since f0ea207ed781 ("iommu/arm-smmu-v3: Introduce struct
arm_smmu_vmaster"), group-wide translated-domain attachment therefore
fails when the first bridge is visited:

  pcieport 0009:00:00.0:
    missing vDEVICE association for translated nested domain:
    cfg=5 ret=-2

  vfio-pci 0009:03:00.0:
    VFIO_DEVICE_ATTACH_IOMMUFD_PT attach failed for pt_id 19: -ENOENT

The same configuration worked with Linux 6.14.

Allow PCI bridges without a vDEVICE to attach without a vmaster.
Endpoint devices still require a vDEVICE, preserving vSID handling for
invalidations and virtual events. Log when the bridge exception is used.

Fixes: f0ea207ed781 ("iommu/arm-smmu-v3: Introduce struct arm_smmu_vmaster")
Cc: [email protected]
Signed-off-by: Dmitry Malkin <[email protected]>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -5,6 +5,8 @@
 
 #include <uapi/linux/iommufd.h>
 
+#include <linux/pci.h>
+
 #include "arm-smmu-v3.h"
 
 void *arm_smmu_hw_info(struct device *dev, u32 *length,
@@ -118,6 +120,17 @@ int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
 		if (cfg == STRTAB_STE_0_CFG_ABORT ||
 		    cfg == STRTAB_STE_0_CFG_BYPASS)
 			return 0;
+		/*
+		 * Group-wide domain attachment also visits host PCI bridges. Such a
+		 * bridge is not exposed to the VM and therefore has no virtual SID.
+		 */
+		if (dev_is_pci(state->master->dev) &&
+		    pci_is_bridge(to_pci_dev(state->master->dev))) {
+			dev_info_ratelimited(state->master->dev,
+					     "skipping vDEVICE requirement for translated nested domain: cfg=%u ret=%d\n",
+					     cfg, ret);
+			return 0;
+		}
 		return ret;
 	}
 
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.