From: Yong Zhao <yong.z...@amd.com>

Because CRAT_CU_FLAGS_IOMMU_PRESENT was not set in some BIOS crat, we
need to workaround this.

For future compatibility, we also overwrite the bit in capability according
to the value of needs_iommu_device.

Signed-off-by: Yong Zhao <yong.z...@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehl...@amd.com>
Signed-off-by: Felix Kuehling <felix.kuehl...@amd.com>
---
 drivers/gpu/drm/amd/amdkfd/kfd_iommu.c    | 13 ++++++++++++-
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h     |  1 +
 drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 21 ++++++++++++++++-----
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c
index 7a61f38..0149475 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c
@@ -62,9 +62,20 @@ int kfd_iommu_device_init(struct kfd_dev *kfd)
        struct amd_iommu_device_info iommu_info;
        unsigned int pasid_limit;
        int err;
+       struct kfd_topology_device *top_dev;
 
-       if (!kfd->device_info->needs_iommu_device)
+       top_dev = kfd_topology_device_by_id(kfd->id);
+
+       /*
+        * Overwrite ATS capability according to needs_iommu_device to fix
+        * potential missing corresponding bit in CRAT of BIOS.
+        */
+       if (!kfd->device_info->needs_iommu_device) {
+               top_dev->node_props.capability &= ~HSA_CAP_ATS_PRESENT;
                return 0;
+       }
+
+       top_dev->node_props.capability |= HSA_CAP_ATS_PRESENT;
 
        iommu_info.flags = 0;
        err = amd_iommu_device_info(kfd->pdev, &iommu_info);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h 
b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 355f79d..87e788c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -778,6 +778,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu);
 int kfd_topology_remove_device(struct kfd_dev *gpu);
 struct kfd_topology_device *kfd_topology_device_by_proximity_domain(
                                                uint32_t proximity_domain);
+struct kfd_topology_device *kfd_topology_device_by_id(uint32_t gpu_id);
 struct kfd_dev *kfd_device_by_id(uint32_t gpu_id);
 struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev);
 int kfd_topology_enum_kfd_devices(uint8_t idx, struct kfd_dev **kdev);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index bc95d4df..80f5db4 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -63,22 +63,33 @@ struct kfd_topology_device 
*kfd_topology_device_by_proximity_domain(
        return device;
 }
 
-struct kfd_dev *kfd_device_by_id(uint32_t gpu_id)
+struct kfd_topology_device *kfd_topology_device_by_id(uint32_t gpu_id)
 {
-       struct kfd_topology_device *top_dev;
-       struct kfd_dev *device = NULL;
+       struct kfd_topology_device *top_dev = NULL;
+       struct kfd_topology_device *ret = NULL;
 
        down_read(&topology_lock);
 
        list_for_each_entry(top_dev, &topology_device_list, list)
                if (top_dev->gpu_id == gpu_id) {
-                       device = top_dev->gpu;
+                       ret = top_dev;
                        break;
                }
 
        up_read(&topology_lock);
 
-       return device;
+       return ret;
+}
+
+struct kfd_dev *kfd_device_by_id(uint32_t gpu_id)
+{
+       struct kfd_topology_device *top_dev;
+
+       top_dev = kfd_topology_device_by_id(gpu_id);
+       if (!top_dev)
+               return NULL;
+
+       return top_dev->gpu;
 }
 
 struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev)
-- 
2.7.4

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to