iommu/amd: Introduce iommu_dev_data.ppr
authorSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Thu, 21 Sep 2023 09:21:44 +0000 (09:21 +0000)
committerJoerg Roedel <jroedel@suse.de>
Mon, 25 Sep 2023 10:39:05 +0000 (12:39 +0200)
For AMD IOMMU, the PPR feature is needed to support IO page fault (IOPF).
PPR is enabled per PCI end-point device, and is configured by the PPR bit
in the IOMMU device table entry (i.e DTE[PPR]).

Introducing struct iommu_dev_data.ppr track PPR setting for each device.

Also iommu_dev_data.ppr will be set only when IOMMU supports PPR. Hence
remove redundant feature support check in set_dte_entry().

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Co-developed-by: Vasant Hegde <vasant.hegde@amd.com>
Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
Link: https://lore.kernel.org/r/20230921092147.5930-12-vasant.hegde@amd.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/amd/amd_iommu_types.h
drivers/iommu/amd/iommu.c

index 1c61dca638242d5e2e13dff78d5168bef896a1df..87fa39c490e8ba08e8757447dbfe6f7e494df6df 100644 (file)
@@ -816,6 +816,7 @@ struct iommu_dev_data {
        u8 ats_enabled  :1;               /* ATS state */
        u8 pri_tlp      :1;               /* PASID TLB required for
                                             PPR completions */
+       u8 ppr          :1;               /* Enable device PPR support */
        bool use_vapic;                   /* Enable device to use vapic mode */
        bool defer_attach;
 
index 4330002769230b69d22b2bac03c2f555636a133d..4ee69ccdc17b17e8fbf34c9aa898b2f9c79bb1d0 100644 (file)
@@ -1638,10 +1638,8 @@ static void set_dte_entry(struct amd_iommu *iommu, u16 devid,
        if (ats)
                flags |= DTE_FLAG_IOTLB;
 
-       if (ppr) {
-               if (check_feature(FEATURE_EPHSUP))
-                       pte_root |= 1ULL << DEV_ENTRY_PPR;
-       }
+       if (ppr)
+               pte_root |= 1ULL << DEV_ENTRY_PPR;
 
        if (domain->flags & PD_IOMMUV2_MASK) {
                u64 gcr3 = iommu_virt_to_phys(domain->gcr3_tbl);
@@ -1734,7 +1732,7 @@ static void do_attach(struct iommu_dev_data *dev_data,
 
        /* Update device table */
        set_dte_entry(iommu, dev_data->devid, domain,
-                     ats, dev_data->iommu_v2);
+                     ats, dev_data->ppr);
        clone_aliases(iommu, dev_data->dev);
 
        device_flush_dte(dev_data);
@@ -2013,7 +2011,7 @@ static void update_device_table(struct protection_domain *domain)
                if (!iommu)
                        continue;
                set_dte_entry(iommu, dev_data->devid, domain,
-                             dev_data->ats_enabled, dev_data->iommu_v2);
+                             dev_data->ats_enabled, dev_data->ppr);
                clone_aliases(iommu, dev_data->dev);
        }
 }