Loading drivers/iommu/amd_iommu.c +43 −0 Original line number Diff line number Diff line Loading @@ -3565,3 +3565,46 @@ void amd_iommu_enable_device_erratum(struct pci_dev *pdev, u32 erratum) dev_data->errata |= (1 << erratum); } EXPORT_SYMBOL(amd_iommu_enable_device_erratum); int amd_iommu_device_info(struct pci_dev *pdev, struct amd_iommu_device_info *info) { int max_pasids; int pos; if (pdev == NULL || info == NULL) return -EINVAL; if (!amd_iommu_v2_supported()) return -EINVAL; memset(info, 0, sizeof(*info)); pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS); if (pos) info->flags |= AMD_IOMMU_DEVICE_FLAG_ATS_SUP; pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); if (pos) info->flags |= AMD_IOMMU_DEVICE_FLAG_PRI_SUP; pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); if (pos) { int features; max_pasids = 1 << (9 * (amd_iommu_max_glx_val + 1)); max_pasids = min(max_pasids, (1 << 20)); info->flags |= AMD_IOMMU_DEVICE_FLAG_PASID_SUP; info->max_pasids = min(pci_max_pasids(pdev), max_pasids); features = pci_pasid_features(pdev); if (features & PCI_PASID_CAP_EXEC) info->flags |= AMD_IOMMU_DEVICE_FLAG_EXEC_SUP; if (features & PCI_PASID_CAP_PRIV) info->flags |= AMD_IOMMU_DEVICE_FLAG_PRIV_SUP; } return 0; } EXPORT_SYMBOL(amd_iommu_device_info); include/linux/amd-iommu.h +26 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,32 @@ typedef int (*amd_iommu_invalid_ppr_cb)(struct pci_dev *pdev, extern int amd_iommu_set_invalid_ppr_cb(struct pci_dev *pdev, amd_iommu_invalid_ppr_cb cb); /** * amd_iommu_device_info() - Get information about IOMMUv2 support of a * PCI device * @pdev: PCI device to query information from * @info: A pointer to an amd_iommu_device_info structure which will contain * the information about the PCI device * * Returns 0 on success, negative value on error */ #define AMD_IOMMU_DEVICE_FLAG_ATS_SUP 0x1 /* ATS feature supported */ #define AMD_IOMMU_DEVICE_FLAG_PRI_SUP 0x2 /* PRI feature supported */ #define AMD_IOMMU_DEVICE_FLAG_PASID_SUP 0x4 /* PASID context supported */ #define AMD_IOMMU_DEVICE_FLAG_EXEC_SUP 0x8 /* Device may request execution on memory pages */ #define AMD_IOMMU_DEVICE_FLAG_PRIV_SUP 0x10 /* Device may request super-user privileges */ struct amd_iommu_device_info { int max_pasids; u32 flags; }; extern int amd_iommu_device_info(struct pci_dev *pdev, struct amd_iommu_device_info *info); #else static inline int amd_iommu_detect(void) { return -ENODEV; } Loading Loading
drivers/iommu/amd_iommu.c +43 −0 Original line number Diff line number Diff line Loading @@ -3565,3 +3565,46 @@ void amd_iommu_enable_device_erratum(struct pci_dev *pdev, u32 erratum) dev_data->errata |= (1 << erratum); } EXPORT_SYMBOL(amd_iommu_enable_device_erratum); int amd_iommu_device_info(struct pci_dev *pdev, struct amd_iommu_device_info *info) { int max_pasids; int pos; if (pdev == NULL || info == NULL) return -EINVAL; if (!amd_iommu_v2_supported()) return -EINVAL; memset(info, 0, sizeof(*info)); pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS); if (pos) info->flags |= AMD_IOMMU_DEVICE_FLAG_ATS_SUP; pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); if (pos) info->flags |= AMD_IOMMU_DEVICE_FLAG_PRI_SUP; pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); if (pos) { int features; max_pasids = 1 << (9 * (amd_iommu_max_glx_val + 1)); max_pasids = min(max_pasids, (1 << 20)); info->flags |= AMD_IOMMU_DEVICE_FLAG_PASID_SUP; info->max_pasids = min(pci_max_pasids(pdev), max_pasids); features = pci_pasid_features(pdev); if (features & PCI_PASID_CAP_EXEC) info->flags |= AMD_IOMMU_DEVICE_FLAG_EXEC_SUP; if (features & PCI_PASID_CAP_PRIV) info->flags |= AMD_IOMMU_DEVICE_FLAG_PRIV_SUP; } return 0; } EXPORT_SYMBOL(amd_iommu_device_info);
include/linux/amd-iommu.h +26 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,32 @@ typedef int (*amd_iommu_invalid_ppr_cb)(struct pci_dev *pdev, extern int amd_iommu_set_invalid_ppr_cb(struct pci_dev *pdev, amd_iommu_invalid_ppr_cb cb); /** * amd_iommu_device_info() - Get information about IOMMUv2 support of a * PCI device * @pdev: PCI device to query information from * @info: A pointer to an amd_iommu_device_info structure which will contain * the information about the PCI device * * Returns 0 on success, negative value on error */ #define AMD_IOMMU_DEVICE_FLAG_ATS_SUP 0x1 /* ATS feature supported */ #define AMD_IOMMU_DEVICE_FLAG_PRI_SUP 0x2 /* PRI feature supported */ #define AMD_IOMMU_DEVICE_FLAG_PASID_SUP 0x4 /* PASID context supported */ #define AMD_IOMMU_DEVICE_FLAG_EXEC_SUP 0x8 /* Device may request execution on memory pages */ #define AMD_IOMMU_DEVICE_FLAG_PRIV_SUP 0x10 /* Device may request super-user privileges */ struct amd_iommu_device_info { int max_pasids; u32 flags; }; extern int amd_iommu_device_info(struct pci_dev *pdev, struct amd_iommu_device_info *info); #else static inline int amd_iommu_detect(void) { return -ENODEV; } Loading