Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iommu/vt-d: Only handle IOPF for SVA when PRI is supported

In intel_svm_set_dev_pasid(), the driver unconditionally manages the IOPF
handling during a domain transition. However, commit a86fb7717320
("iommu/vt-d: Allow SVA with device-specific IOPF") introduced support for
SVA on devices that handle page faults internally without utilizing the
PCI PRI. On such devices, the IOMMU-side IOPF infrastructure is not
required. Calling iopf_for_domain_replace() on these devices is incorrect
and can lead to unexpected failures during PASID attachment or unwinding.

Add a check for info->pri_supported to ensure that the IOPF queue logic
is only invoked for devices that actually rely on the IOMMU's PRI-based
fault handling.

Fixes: 17fce9d2336d ("iommu/vt-d: Put iopf enablement in domain attach path")
Cc: stable@vger.kernel.org
Suggested-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Link: https://lore.kernel.org/r/20260310075520.295104-1-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>

authored by

Lu Baolu and committed by
Joerg Roedel
39c20c4e fe89277c

+8 -4
+8 -4
drivers/iommu/intel/svm.c
··· 164 164 if (IS_ERR(dev_pasid)) 165 165 return PTR_ERR(dev_pasid); 166 166 167 - ret = iopf_for_domain_replace(domain, old, dev); 168 - if (ret) 169 - goto out_remove_dev_pasid; 167 + /* SVA with non-IOMMU/PRI IOPF handling is allowed. */ 168 + if (info->pri_supported) { 169 + ret = iopf_for_domain_replace(domain, old, dev); 170 + if (ret) 171 + goto out_remove_dev_pasid; 172 + } 170 173 171 174 /* Setup the pasid table: */ 172 175 sflags = cpu_feature_enabled(X86_FEATURE_LA57) ? PASID_FLAG_FL5LP : 0; ··· 184 181 185 182 return 0; 186 183 out_unwind_iopf: 187 - iopf_for_domain_replace(old, domain, dev); 184 + if (info->pri_supported) 185 + iopf_for_domain_replace(old, domain, dev); 188 186 out_remove_dev_pasid: 189 187 domain_remove_dev_pasid(domain, dev, pasid); 190 188 return ret;