iommu/amd: Add support for using AMD IOMMU v2 page table for DMA-API
authorSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Thu, 25 Aug 2022 06:39:38 +0000 (06:39 +0000)
committerJoerg Roedel <jroedel@suse.de>
Wed, 7 Sep 2022 14:12:37 +0000 (16:12 +0200)
Introduce init function for setting up DMA domain for DMA-API with
the IOMMU v2 page table.

Co-developed-by: Vasant Hegde <vasant.hegde@amd.com>
Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Link: https://lore.kernel.org/r/20220825063939.8360-9-vasant.hegde@amd.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/amd/iommu.c

index 6abc338dc2073ae8b543b520789be401e4c4fd3f..6bfcac8de1f4f8708ad25a4591ad169a54f4f4d9 100644 (file)
@@ -1653,6 +1653,10 @@ static void do_attach(struct iommu_dev_data *dev_data,
        domain->dev_iommu[iommu->index] += 1;
        domain->dev_cnt                 += 1;
 
+       /* Override supported page sizes */
+       if (domain->flags & PD_GIOV_MASK)
+               domain->domain.pgsize_bitmap = AMD_IOMMU_PGSIZES_V2;
+
        /* Update device table */
        set_dte_entry(iommu, dev_data->devid, domain,
                      ats, dev_data->iommu_v2);
@@ -2032,6 +2036,24 @@ static int protection_domain_init_v1(struct protection_domain *domain, int mode)
        return 0;
 }
 
+static int protection_domain_init_v2(struct protection_domain *domain)
+{
+       spin_lock_init(&domain->lock);
+       domain->id = domain_id_alloc();
+       if (!domain->id)
+               return -ENOMEM;
+       INIT_LIST_HEAD(&domain->dev_list);
+
+       domain->flags |= PD_GIOV_MASK;
+
+       if (domain_enable_v2(domain, 1)) {
+               domain_id_free(domain->id);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
 static struct protection_domain *protection_domain_alloc(unsigned int type)
 {
        struct io_pgtable_ops *pgtbl_ops;
@@ -2059,6 +2081,9 @@ static struct protection_domain *protection_domain_alloc(unsigned int type)
        case AMD_IOMMU_V1:
                ret = protection_domain_init_v1(domain, mode);
                break;
+       case AMD_IOMMU_V2:
+               ret = protection_domain_init_v2(domain);
+               break;
        default:
                ret = -EINVAL;
        }