> From: Liu, Yi L <yi.l.liu@xxxxxxxxx> > Sent: Friday, April 12, 2024 4:21 PM > > +static int vfio_pci_core_feature_pasid(struct vfio_device *device, u32 flags, > + struct vfio_device_feature_pasid __user > *arg, > + size_t argsz) > +{ > + struct vfio_pci_core_device *vdev = > + container_of(device, struct vfio_pci_core_device, vdev); > + struct vfio_device_feature_pasid pasid = { 0 }; > + struct pci_dev *pdev = vdev->pdev; > + u32 capabilities = 0; > + u16 ctrl = 0; > + int ret; > + > + /* > + * Due to no PASID capability per VF, to be consistent, we do not > + * support SET of the PASID capability for both PF and VF. > + */ /* Disallow SET of the PASID capability given it is shared by all VF's * and configured implicitly by the IOMMU driver. */ > + ret = vfio_check_feature(flags, argsz, VFIO_DEVICE_FEATURE_GET, > + sizeof(pasid)); > + if (ret != 1) > + return ret; > + > + /* VF shares the PASID capability of its PF */ > + if (pdev->is_virtfn) > + pdev = pci_physfn(pdev); > + > + if (!pdev->pasid_enabled) > + goto out; > + > +#ifdef CONFIG_PCI_PASID > + pci_read_config_dword(pdev, pdev->pasid_cap + PCI_PASID_CAP, > + &capabilities); > + pci_read_config_word(pdev, pdev->pasid_cap + PCI_PASID_CTRL, > + &ctrl); > +#endif > + > + pasid.width = (capabilities >> 8) & 0x1f; it's cleaner to have helpers instead of directly checking CONFIG_PCI_XXX here. there is an existing helper for the width: pci_max_pasids() pci_pasid_features() can report supported features but not the actual enabled set. for enabled features it's already stored in pdev->pasid_features. so what's required here is probably a new pci_pasid_enabled_features() to return that field.