Skip to contentSkip to conversation

iommu/vt-d: Flush old iommu caches for kdump when the device gets context mapped

PATCH Applied Xunlei Pang 4 participants 6 messages Dec 5, 2016 – Jan 4, 2017 IOMMU

lore
Share & tools
lore
#0 lore raw

PATCH v3 1/1 iommu/vt-d: Flush old iommu caches for kdump when the device gets context mapped

We met the DMAR fault both on hpsa P420i and P421 SmartArray controllers
under kdump, it can be steadily reproduced on several different machines,
the dmesg log is like:
HP HPSA Driver (v 3.4.16-0)
hpsa 0000:02:00.0: using doorbell to reset controller
hpsa 0000:02:00.0: board ready after hard reset.
hpsa 0000:02:00.0: Waiting for controller to respond to no-op
DMAR: Setting identity map for device 0000:02:00.0 [0xe8000 - 0xe8fff]
DMAR: Setting identity map for device 0000:02:00.0 [0xf4000 - 0xf4fff]
DMAR: Setting identity map for device 0000:02:00.0 [0xbdf6e000 - 0xbdf6efff]
DMAR: Setting identity map for device 0000:02:00.0 [0xbdf6f000 - 0xbdf7efff]
DMAR: Setting identity map for device 0000:02:00.0 [0xbdf7f000 - 0xbdf82fff]
DMAR: Setting identity map for device 0000:02:00.0 [0xbdf83000 - 0xbdf84fff]
DMAR: DRHD: handling fault status reg 2
DMAR: [DMA Read] Request device [02:00.0] fault addr fffff000 [fault reason 06] PTE Read access is not set hpsa 0000:02:00.0: controller message 03:00 timed out
hpsa 0000:02:00.0: no-op failed; re-trying

After some debugging, we found that the fault addr is from DMA initiated at the driver probe stage after reset(not in-flight DMA), and the corresponding pte entry value is correct, the fault is likely due to the old iommu caches of the in-flight DMA before it.

Thus we need to flush the old cache after context mapping is setup for the device, where the device is supposed to finish reset at its driver probe stage and no in-flight DMA exists hereafter.

I'm not sure if the hardware is responsible for invalidating all the related caches allocated in the iommu hardware before, but seems not the case for hpsa, actually many device drivers have problems in properly resetting the hardware. Anyway flushing (again) by software in kdump kernel when the device gets context mapped which is a quite infrequent operation does little harm.

With this patch, the problematic machine can survive the kdump tests.

CC Myron Stowe <[email protected]>
CC Joseph Szczypek <[email protected]>
CC Don Brace <[email protected]>
CC Baoquan He <[email protected]>
CC Dave Young <[email protected]>
Fixes 091d42e43d21 ("iommu/vt-d: Copy translation tables from old kernel")
Fixes dbcd861f252d ("iommu/vt-d: Do not re-use domain-ids from the old kernel")
Fixes cf484d0e6939 ("iommu/vt-d: Mark copied context entries")

---
v2->v3:
Flush context cache only and add Fixes-tag, according to Joerg's comments.

 drivers/iommu/intel-iommu.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
drivers/iommu/intel-iommu.c +19 -0
index 3965e73..624eac9 100644
@@ -2024,6 +2024,25 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
 	if (context_present(context))
 		goto out_unlock;
 
+	/*
+	 * For kdump cases, old valid entries may be cached due to the
+	 * in-flight DMA and copied pgtable, but there is no unmapping
+	 * behaviour for them, thus we need an explicit cache flush for
+	 * the newly-mapped device. For kdump, at this point, the device
+	 * is supposed to finish reset at its driver probe stage, so no
+	 * in-flight DMA will exist, and we don't need to worry anymore
+	 * hereafter.
+	 */
+	if (context_copied(context)) {
+		u16 did_old = context_domain_id(context);
+
+		if (did_old >= 0 && did_old < cap_ndoms(iommu->cap))
+			iommu->flush.flush_context(iommu, did_old,
+						   (((u16)bus) << 8) | devfn,
+						   DMA_CCMD_MASK_NOBIT,
+						   DMA_CCMD_DEVICE_INVL);
+	}
+
 	pgd = domain->pgd;
 
 	context_clear_entry(context);
Signature · 1 line
1.8.3.1
maintainer Applied
#1 lore raw
Quoted 2 lines · Xunlei Pang
 drivers/iommu/intel-iommu.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

Applied, thanks.

#2 lore raw
Quoted 5 lines · Joerg Roedel
Quoted 2 lines · Xunlei Pang
 drivers/iommu/intel-iommu.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

Applied, thanks.

Joerg:

This didn't seem to make the 4.10 merge window. Was that on purpose? Any idea when you might include this in a pull request for Linus?

Myron

Quoted 1 line
maintainer
#3 lore raw
Quoted 2 lines · Myron Stowe

This didn't seem to make the 4.10 merge window. Was that on purpose? Any idea when you might include this in a pull request for Linus?

I will collect fixes this week and send them to Linus, they will also include this patch.

Joerg

Tested-by on v3 1/1
#4 lore raw
In reply to Xunlei Pang
Quoted 100 lines

-----Original Message-----
From: Xunlei Pang [mailto:[email protected]]
Sent: Monday, December 05, 2016 6:09 AM
To: Joerg Roedel; David Woodhouse
Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org; [email protected]; Xunlei Pang; Myron Stowe; Joseph Szczypek; Don Brace; Baoquan He; Dave Young
Subject: [PATCH v3] iommu/vt-d: Flush old iommu caches for kdump when
the device gets context mapped

EXTERNAL EMAIL

We met the DMAR fault both on hpsa P420i and P421 SmartArray controllers under kdump, it can be steadily reproduced on several different machines, the dmesg log is like:
HP HPSA Driver (v 3.4.16-0)
hpsa 0000:02:00.0: using doorbell to reset controller
hpsa 0000:02:00.0: board ready after hard reset.
hpsa 0000:02:00.0: Waiting for controller to respond to no-op
DMAR: Setting identity map for device 0000:02:00.0 [0xe8000 - 0xe8fff]
DMAR: Setting identity map for device 0000:02:00.0 [0xf4000 - 0xf4fff]
DMAR: Setting identity map for device 0000:02:00.0 [0xbdf6e000 - 0xbdf6efff]
DMAR: Setting identity map for device 0000:02:00.0 [0xbdf6f000 - 0xbdf7efff]
DMAR: Setting identity map for device 0000:02:00.0 [0xbdf7f000 - 0xbdf82fff]
DMAR: Setting identity map for device 0000:02:00.0 [0xbdf83000 - 0xbdf84fff]
DMAR: DRHD: handling fault status reg 2
DMAR: [DMA Read] Request device [02:00.0] fault addr fffff000 [fault reason 06] PTE Read access is not set
hpsa 0000:02:00.0: controller message 03:00 timed out
hpsa 0000:02:00.0: no-op failed; re-trying

After some debugging, we found that the fault addr is from DMA initiated at the driver probe stage after reset(not in-flight DMA), and the corresponding pte entry value is correct, the fault is likely due to the old iommu caches of the in-flight DMA before it.

Thus we need to flush the old cache after context mapping is setup for the device, where the device is supposed to finish reset at its driver probe stage and no in-flight DMA exists hereafter.

I'm not sure if the hardware is responsible for invalidating all the related caches allocated in the iommu hardware before, but seems not the case for hpsa,
actually many device drivers have problems in properly resetting the hardware.
Anyway flushing (again) by software in kdump kernel when the device gets context
mapped which is a quite infrequent operation does little harm.

With this patch, the problematic machine can survive the kdump tests.

CC Myron Stowe <[email protected]>
CC Joseph Szczypek <[email protected]>
CC Don Brace <don.brace-dzo6w/[email protected]>
CC Baoquan He <[email protected]>
CC Dave Young <[email protected]>
Fixes 091d42e43d21 ("iommu/vt-d: Copy translation tables from old kernel")
Fixes dbcd861f252d ("iommu/vt-d: Do not re-use domain-ids from the old

kernel")

Fixes cf484d0e6939 ("iommu/vt-d: Mark copied context entries")

---
v2->v3:
Flush context cache only and add Fixes-tag, according to Joerg's comments.

 drivers/iommu/intel-iommu.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
drivers/iommu/intel-iommu.c +19 -0
index 3965e73..624eac9 100644
@@ -2024,6 +2024,25 @@ static int domain_context_mapping_one(struct
 dmar_domain *domain,
        if (context_present(context))
                goto out_unlock;
 
+       /*
+        * For kdump cases, old valid entries may be cached due to the
+        * in-flight DMA and copied pgtable, but there is no unmapping
+        * behaviour for them, thus we need an explicit cache flush for
+        * the newly-mapped device. For kdump, at this point, the device
+        * is supposed to finish reset at its driver probe stage, so no
+        * in-flight DMA will exist, and we don't need to worry anymore
+        * hereafter.
+        */
+       if (context_copied(context)) {
+               u16 did_old = context_domain_id(context);
+
+               if (did_old >= 0 && did_old < cap_ndoms(iommu->cap))
+                       iommu->flush.flush_context(iommu, did_old,
+                                                  (((u16)bus) << 8) | devfn,
+                                                  DMA_CCMD_MASK_NOBIT,
+                                                  DMA_CCMD_DEVICE_INVL);
+       }
+
        pgd = domain->pgd;
 
        context_clear_entry(context);
Quoted 2 lines

--
1.8.3.1

Thanks,
Don Brace
ESC - Smart Storage
Microsemi Corporation

maintainer Applied
#5 lore raw
In reply to Xunlei Pang
Quoted 5 lines · Xunlei Pang

v2->v3:
Flush context cache only and add Fixes-tag, according to Joerg's comments.

 drivers/iommu/intel-iommu.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

Applied to the fixes branch, thanks.