AMD IOMMU introduces support for Guest I/O protection where the request
from the I/O device without a PASID are treated as if they have PASID 0.

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpa...@amd.com>
---
 drivers/iommu/amd/amd_iommu_types.h | 3 +++
 drivers/iommu/amd/init.c            | 8 ++++++++
 drivers/iommu/amd/iommu.c           | 4 ++++
 3 files changed, 15 insertions(+)

diff --git a/drivers/iommu/amd/amd_iommu_types.h 
b/drivers/iommu/amd/amd_iommu_types.h
index 25062eb86c8b..876ba1adf73e 100644
--- a/drivers/iommu/amd/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -93,6 +93,7 @@
 #define FEATURE_HE             (1ULL<<8)
 #define FEATURE_PC             (1ULL<<9)
 #define FEATURE_GAM_VAPIC      (1ULL<<21)
+#define FEATURE_GIOSUP         (1ULL<<48)
 #define FEATURE_EPHSUP         (1ULL<<50)
 #define FEATURE_SNP            (1ULL<<63)
 
@@ -366,6 +367,7 @@
 #define DTE_FLAG_IW (1ULL << 62)
 
 #define DTE_FLAG_IOTLB (1ULL << 32)
+#define DTE_FLAG_GIOV  (1ULL << 54)
 #define DTE_FLAG_GV    (1ULL << 55)
 #define DTE_FLAG_MASK  (0x3ffULL << 32)
 #define DTE_GLX_SHIFT  (56)
@@ -519,6 +521,7 @@ struct protection_domain {
        spinlock_t lock;        /* mostly used to lock the page table*/
        u16 id;                 /* the domain id written to the device table */
        int glx;                /* Number of levels for GCR3 table */
+       bool giov;              /* guest IO protection domain */
        u64 *gcr3_tbl;          /* Guest CR3 table */
        unsigned long flags;    /* flags to find out type of domain */
        unsigned dev_cnt;       /* devices assigned to this domain */
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index 5def566de6f6..9265c1bf1d84 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -1895,6 +1895,12 @@ static int __init iommu_init_pci(struct amd_iommu *iommu)
 
        init_iommu_perf_ctr(iommu);
 
+       if (amd_iommu_pgtable == AMD_IOMMU_V2 &&
+           !iommu_feature(iommu, FEATURE_GIOSUP)) {
+               pr_warn("Cannot enable v2 page table for DMA-API. Fallback to 
v1.\n");
+               amd_iommu_pgtable = AMD_IOMMU_V1;
+       }
+
        if (is_rd890_iommu(iommu->dev)) {
                int i, j;
 
@@ -1969,6 +1975,8 @@ static void print_iommu_info(void)
                if (amd_iommu_xt_mode == IRQ_REMAP_X2APIC_MODE)
                        pr_info("X2APIC enabled\n");
        }
+       if (amd_iommu_pgtable == AMD_IOMMU_V2)
+               pr_info("GIOV enabled\n");
 }
 
 static int __init amd_iommu_init_pci(void)
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index f3800efdbb29..e29ece6e1e68 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -1405,6 +1405,10 @@ static void set_dte_entry(u16 devid, struct 
protection_domain *domain,
 
        pte_root |= (domain->iop.mode & DEV_ENTRY_MODE_MASK)
                    << DEV_ENTRY_MODE_SHIFT;
+
+       if (domain->giov && (domain->flags & PD_IOMMUV2_MASK))
+               pte_root |= DTE_FLAG_GIOV;
+
        pte_root |= DTE_FLAG_IR | DTE_FLAG_IW | DTE_FLAG_V | DTE_FLAG_TV;
 
        flags = amd_iommu_dev_table[devid].data[1];
-- 
2.17.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to