Re: [PATCH v1 3/3] iommu/vt-d: Fix Unexpected page request in Privilege Mode

2021-08-17 Thread Lu Baolu

On 2021/8/17 12:24, Liu Yi L wrote:

This patch fixes the below error. This is due to improper iotlb invalidation
in intel_pasid_tear_down_entry().

[  180.187556] Unexpected page request in Privilege Mode
[  180.187565] Unexpected page request in Privilege Mode
[  180.279933] Unexpected page request in Privilege Mode
[  180.279937] Unexpected page request in Privilege Mode

Per chapter 6.5.3.3 of VT-d spec 3.3, when tear down a pasid entry, software
should use Domain selective IOTLB flush if the PGTT of the pasid entry is
SL only or Nested, while for the pasid entries whose PGTT is FL only or PT
using PASID-based IOTLB flush is enough.

Fixes: 1c4f88b7f1f9 ("iommu/vt-d: Shared virtual address in scalable mode")
Cc: Lu Baolu
Signed-off-by: Kumar Sanjay K
Signed-off-by: Liu Yi L
Tested-by: Yi Sun


Good catch! Thanks!

It has been queued for iommu/fix.

Best regards,
baolu
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 3/3] iommu/vt-d: Fix Unexpected page request in Privilege Mode

2021-08-16 Thread Liu Yi L
This patch fixes the below error. This is due to improper iotlb invalidation
in intel_pasid_tear_down_entry().

[  180.187556] Unexpected page request in Privilege Mode
[  180.187565] Unexpected page request in Privilege Mode
[  180.279933] Unexpected page request in Privilege Mode
[  180.279937] Unexpected page request in Privilege Mode

Per chapter 6.5.3.3 of VT-d spec 3.3, when tear down a pasid entry, software
should use Domain selective IOTLB flush if the PGTT of the pasid entry is
SL only or Nested, while for the pasid entries whose PGTT is FL only or PT
using PASID-based IOTLB flush is enough.

Fixes: 1c4f88b7f1f9 ("iommu/vt-d: Shared virtual address in scalable mode")
Cc: Lu Baolu 
Signed-off-by: Kumar Sanjay K 
Signed-off-by: Liu Yi L 
Tested-by: Yi Sun 
---
 drivers/iommu/intel/pasid.c | 10 --
 drivers/iommu/intel/pasid.h |  5 +
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
index b1d0c2945c9a..07c390aed1fe 100644
--- a/drivers/iommu/intel/pasid.c
+++ b/drivers/iommu/intel/pasid.c
@@ -511,7 +511,7 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu, 
struct device *dev,
 u32 pasid, bool fault_ignore)
 {
struct pasid_entry *pte;
-   u16 did;
+   u16 did, pgtt;
 
pte = intel_pasid_get_entry(dev, pasid);
if (WARN_ON(!pte))
@@ -521,13 +521,19 @@ void intel_pasid_tear_down_entry(struct intel_iommu 
*iommu, struct device *dev,
return;
 
did = pasid_get_domain_id(pte);
+   pgtt = pasid_pte_get_pgtt(pte);
+
intel_pasid_clear_entry(dev, pasid, fault_ignore);
 
if (!ecap_coherent(iommu->ecap))
clflush_cache_range(pte, sizeof(*pte));
 
pasid_cache_invalidation_with_pasid(iommu, did, pasid);
-   qi_flush_piotlb(iommu, did, pasid, 0, -1, 0);
+
+   if (pgtt == PASID_ENTRY_PGTT_PT || pgtt == PASID_ENTRY_PGTT_FL_ONLY)
+   qi_flush_piotlb(iommu, did, pasid, 0, -1, 0);
+   else
+   iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
 
/* Device IOTLB doesn't need to be flushed in caching mode. */
if (!cap_caching_mode(iommu->cap))
diff --git a/drivers/iommu/intel/pasid.h b/drivers/iommu/intel/pasid.h
index 5ff61c3d401f..637141d71092 100644
--- a/drivers/iommu/intel/pasid.h
+++ b/drivers/iommu/intel/pasid.h
@@ -99,6 +99,11 @@ static inline bool pasid_pte_is_present(struct pasid_entry 
*pte)
return READ_ONCE(pte->val[0]) & PASID_PTE_PRESENT;
 }
 
+static inline u16 pasid_pte_get_pgtt(struct pasid_entry *pte)
+{
+   return (READ_ONCE(pte->val[0]) >> 6) & 0x7;
+}
+
 extern unsigned int intel_pasid_max_id;
 int intel_pasid_alloc_table(struct device *dev);
 void intel_pasid_free_table(struct device *dev);
-- 
2.25.1

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