OSDN Git Service

iommu/vt-d: Add present bit check in pasid entry setup helpers
authorLiu Yi L <yi.l.liu@intel.com>
Wed, 18 Aug 2021 13:48:52 +0000 (21:48 +0800)
committerJoerg Roedel <jroedel@suse.de>
Thu, 19 Aug 2021 08:41:08 +0000 (10:41 +0200)
The helper functions should not modify the pasid entries which are still
in use. Add a check against present bit.

Signed-off-by: Liu Yi L <yi.l.liu@intel.com>
Link: https://lore.kernel.org/r/20210817042425.1784279-1-yi.l.liu@intel.com
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Link: https://lore.kernel.org/r/20210818134852.1847070-10-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/intel/pasid.c

index 02e1049..b1d0c29 100644 (file)
@@ -534,6 +534,10 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev,
                devtlb_invalidation_with_pasid(iommu, dev, pasid);
 }
 
+/*
+ * This function flushes cache for a newly setup pasid table entry.
+ * Caller of it should not modify the in-use pasid table entries.
+ */
 static void pasid_flush_caches(struct intel_iommu *iommu,
                                struct pasid_entry *pte,
                               u32 pasid, u16 did)
@@ -585,6 +589,10 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
        if (WARN_ON(!pte))
                return -EINVAL;
 
+       /* Caller must ensure PASID entry is not in use. */
+       if (pasid_pte_is_present(pte))
+               return -EBUSY;
+
        pasid_clear_entry(pte);
 
        /* Setup the first level page table pointer: */
@@ -684,6 +692,10 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
                return -ENODEV;
        }
 
+       /* Caller must ensure PASID entry is not in use. */
+       if (pasid_pte_is_present(pte))
+               return -EBUSY;
+
        pasid_clear_entry(pte);
        pasid_set_domain_id(pte, did);
        pasid_set_slptr(pte, pgd_val);
@@ -723,6 +735,10 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
                return -ENODEV;
        }
 
+       /* Caller must ensure PASID entry is not in use. */
+       if (pasid_pte_is_present(pte))
+               return -EBUSY;
+
        pasid_clear_entry(pte);
        pasid_set_domain_id(pte, did);
        pasid_set_address_width(pte, iommu->agaw);