···35653565 dev_data->errata |= (1 << erratum);35663566}35673567EXPORT_SYMBOL(amd_iommu_enable_device_erratum);35683568+35693569+int amd_iommu_device_info(struct pci_dev *pdev,35703570+ struct amd_iommu_device_info *info)35713571+{35723572+ int max_pasids;35733573+ int pos;35743574+35753575+ if (pdev == NULL || info == NULL)35763576+ return -EINVAL;35773577+35783578+ if (!amd_iommu_v2_supported())35793579+ return -EINVAL;35803580+35813581+ memset(info, 0, sizeof(*info));35823582+35833583+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS);35843584+ if (pos)35853585+ info->flags |= AMD_IOMMU_DEVICE_FLAG_ATS_SUP;35863586+35873587+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);35883588+ if (pos)35893589+ info->flags |= AMD_IOMMU_DEVICE_FLAG_PRI_SUP;35903590+35913591+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);35923592+ if (pos) {35933593+ int features;35943594+35953595+ max_pasids = 1 << (9 * (amd_iommu_max_glx_val + 1));35963596+ max_pasids = min(max_pasids, (1 << 20));35973597+35983598+ info->flags |= AMD_IOMMU_DEVICE_FLAG_PASID_SUP;35993599+ info->max_pasids = min(pci_max_pasids(pdev), max_pasids);36003600+36013601+ features = pci_pasid_features(pdev);36023602+ if (features & PCI_PASID_CAP_EXEC)36033603+ info->flags |= AMD_IOMMU_DEVICE_FLAG_EXEC_SUP;36043604+ if (features & PCI_PASID_CAP_PRIV)36053605+ info->flags |= AMD_IOMMU_DEVICE_FLAG_PRIV_SUP;36063606+ }36073607+36083608+ return 0;36093609+}36103610+EXPORT_SYMBOL(amd_iommu_device_info);
+26
include/linux/amd-iommu.h
···119119extern int amd_iommu_set_invalid_ppr_cb(struct pci_dev *pdev,120120 amd_iommu_invalid_ppr_cb cb);121121122122+/**123123+ * amd_iommu_device_info() - Get information about IOMMUv2 support of a124124+ * PCI device125125+ * @pdev: PCI device to query information from126126+ * @info: A pointer to an amd_iommu_device_info structure which will contain127127+ * the information about the PCI device128128+ *129129+ * Returns 0 on success, negative value on error130130+ */131131+132132+#define AMD_IOMMU_DEVICE_FLAG_ATS_SUP 0x1 /* ATS feature supported */133133+#define AMD_IOMMU_DEVICE_FLAG_PRI_SUP 0x2 /* PRI feature supported */134134+#define AMD_IOMMU_DEVICE_FLAG_PASID_SUP 0x4 /* PASID context supported */135135+#define AMD_IOMMU_DEVICE_FLAG_EXEC_SUP 0x8 /* Device may request execution136136+ on memory pages */137137+#define AMD_IOMMU_DEVICE_FLAG_PRIV_SUP 0x10 /* Device may request138138+ super-user privileges */139139+140140+struct amd_iommu_device_info {141141+ int max_pasids;142142+ u32 flags;143143+};144144+145145+extern int amd_iommu_device_info(struct pci_dev *pdev,146146+ struct amd_iommu_device_info *info);147147+122148#else123149124150static inline int amd_iommu_detect(void) { return -ENODEV; }