]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iommu/amd: Implement global identity domain
authorVasant Hegde <vasant.hegde@amd.com>
Mon, 28 Oct 2024 09:38:08 +0000 (09:38 +0000)
committerJoerg Roedel <jroedel@suse.de>
Tue, 29 Oct 2024 09:08:22 +0000 (10:08 +0100)
Implement global identity domain. All device groups in identity domain
will share this domain.

In attach device path, based on device capability it will allocate per
device domain ID and GCR3 table. So that it can support SVA.

Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Link: https://lore.kernel.org/r/20241028093810.5901-11-vasant.hegde@amd.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/amd/amd_iommu.h
drivers/iommu/amd/init.c
drivers/iommu/amd/iommu.c

index 3b6c6332b09fb8801a8dd4ebc267d11e25c48721..38509e1019e9332f6b7dae78b8ba32e244cdebcc 100644 (file)
@@ -46,6 +46,7 @@ extern int amd_iommu_gpt_level;
 extern unsigned long amd_iommu_pgsize_bitmap;
 
 /* Protection domain ops */
+void amd_iommu_init_identity_domain(void);
 struct protection_domain *protection_domain_alloc(unsigned int type, int nid);
 void protection_domain_free(struct protection_domain *domain);
 struct iommu_domain *amd_iommu_domain_alloc_sva(struct device *dev,
index 7c883be225599dc1b44421f9bbff35f4ced8c024..45fdba48d54dbca1d26677e59ecf35366c14e5ab 100644 (file)
@@ -2164,6 +2164,9 @@ static int __init amd_iommu_init_pci(void)
        struct amd_iommu_pci_seg *pci_seg;
        int ret;
 
+       /* Init global identity domain before registering IOMMU */
+       amd_iommu_init_identity_domain();
+
        for_each_iommu(iommu) {
                ret = iommu_init_pci(iommu);
                if (ret) {
index 671131c22d9d39baa88dd7be0c1e471e727231dc..477aaf76b7ad0f819879f5c038d8d37e2d51b09d 100644 (file)
@@ -74,6 +74,9 @@ struct kmem_cache *amd_iommu_irq_cache;
 
 static void detach_device(struct device *dev);
 
+static int amd_iommu_attach_device(struct iommu_domain *dom,
+                                  struct device *dev);
+
 static void set_dte_entry(struct amd_iommu *iommu,
                          struct iommu_dev_data *dev_data);
 
@@ -2263,6 +2266,14 @@ void protection_domain_free(struct protection_domain *domain)
        kfree(domain);
 }
 
+static void protection_domain_init(struct protection_domain *domain, int nid)
+{
+       spin_lock_init(&domain->lock);
+       INIT_LIST_HEAD(&domain->dev_list);
+       INIT_LIST_HEAD(&domain->dev_data_list);
+       domain->iop.pgtbl.cfg.amd.nid = nid;
+}
+
 struct protection_domain *protection_domain_alloc(unsigned int type, int nid)
 {
        struct protection_domain *domain;
@@ -2277,10 +2288,7 @@ struct protection_domain *protection_domain_alloc(unsigned int type, int nid)
                return NULL;
        }
 
-       spin_lock_init(&domain->lock);
-       INIT_LIST_HEAD(&domain->dev_list);
-       INIT_LIST_HEAD(&domain->dev_data_list);
-       domain->iop.pgtbl.cfg.amd.nid = nid;
+       protection_domain_init(domain, nid);
 
        return domain;
 }
@@ -2471,6 +2479,25 @@ static struct iommu_domain blocked_domain = {
        }
 };
 
+static struct protection_domain identity_domain;
+
+static const struct iommu_domain_ops identity_domain_ops = {
+       .attach_dev = amd_iommu_attach_device,
+};
+
+void amd_iommu_init_identity_domain(void)
+{
+       struct iommu_domain *domain = &identity_domain.domain;
+
+       domain->type = IOMMU_DOMAIN_IDENTITY;
+       domain->ops = &identity_domain_ops;
+       domain->owner = &amd_iommu_ops;
+
+       identity_domain.id = domain_id_alloc();
+
+       protection_domain_init(&identity_domain, NUMA_NO_NODE);
+}
+
 static int amd_iommu_attach_device(struct iommu_domain *dom,
                                   struct device *dev)
 {
@@ -2869,6 +2896,7 @@ static int amd_iommu_dev_disable_feature(struct device *dev,
 const struct iommu_ops amd_iommu_ops = {
        .capable = amd_iommu_capable,
        .blocked_domain = &blocked_domain,
+       .identity_domain = &identity_domain.domain,
        .domain_alloc = amd_iommu_domain_alloc,
        .domain_alloc_user = amd_iommu_domain_alloc_user,
        .domain_alloc_sva = amd_iommu_domain_alloc_sva,