ioat2: catch and recover from broken vtd configurations v6
This commit is contained in:
parent
4038895354
commit
4b57f309c7
167
ioat2-catch-and-recover-from-broken-vtd-configurations.patch
Normal file
167
ioat2-catch-and-recover-from-broken-vtd-configurations.patch
Normal file
@ -0,0 +1,167 @@
|
||||
From 547c01ae2608ffe89d18441ea209aff0540e83ec Mon Sep 17 00:00:00 2001
|
||||
From: Kyle McMartin <kyle@mcmartin.ca>
|
||||
Date: Thu, 9 Dec 2010 17:45:58 -0500
|
||||
Subject: ioat2: catch and recover from broken vtd configurations v6
|
||||
|
||||
On some platforms (MacPro3,1) the BIOS assigns the ioatdma device to the
|
||||
incorrect iommu causing faults when the driver initializes. Add a quirk
|
||||
to catch this misconfiguration and try falling back to untranslated
|
||||
operation (which works in the MacPro3,1 case).
|
||||
|
||||
Assuming there are other platforms with misconfigured iommus teach the
|
||||
ioatdma driver to treat initialization failures as non-fatal (just fail
|
||||
the driver load and emit a warning instead of triggering a BUG_ON).
|
||||
|
||||
This can be classified as a boot regression since 2.6.32 on affected
|
||||
platforms since the ioatdma module did not autoload prior to that
|
||||
kernel.
|
||||
|
||||
Cc: <stable@kernel.org>
|
||||
Acked-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Reported-by: Chris Li <lkml@chrisli.org>
|
||||
Tested-by: Chris Li <lkml@chrisli.org>
|
||||
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
|
||||
|
||||
Conflicts:
|
||||
|
||||
drivers/dma/ioat/dma.h
|
||||
---
|
||||
drivers/dma/ioat/dma.h | 1 +
|
||||
drivers/dma/ioat/dma_v2.c | 24 ++++++++++++++++++++++--
|
||||
drivers/dma/ioat/dma_v3.c | 5 ++++-
|
||||
drivers/pci/intel-iommu.c | 28 ++++++++++++++++++++++++++++
|
||||
4 files changed, 55 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h
|
||||
index 86b97ac..f7619e9 100644
|
||||
--- a/drivers/dma/ioat/dma.h
|
||||
+++ b/drivers/dma/ioat/dma.h
|
||||
@@ -96,6 +96,7 @@ struct ioat_chan_common {
|
||||
#define IOAT_COMPLETION_ACK 1
|
||||
#define IOAT_RESET_PENDING 2
|
||||
#define IOAT_KOBJ_INIT_FAIL 3
|
||||
+ #define IOAT_RUN 4
|
||||
struct timer_list timer;
|
||||
#define COMPLETION_TIMEOUT msecs_to_jiffies(100)
|
||||
#define IDLE_TIMEOUT msecs_to_jiffies(2000)
|
||||
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
|
||||
index b5ae56c..63e6929 100644
|
||||
--- a/drivers/dma/ioat/dma_v2.c
|
||||
+++ b/drivers/dma/ioat/dma_v2.c
|
||||
@@ -304,7 +304,10 @@ void ioat2_timer_event(unsigned long data)
|
||||
chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
|
||||
dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
|
||||
__func__, chanerr);
|
||||
- BUG_ON(is_ioat_bug(chanerr));
|
||||
+ if (test_bit(IOAT_RUN, &chan->state))
|
||||
+ BUG_ON(is_ioat_bug(chanerr));
|
||||
+ else /* we never got off the ground */
|
||||
+ return;
|
||||
}
|
||||
|
||||
/* if we haven't made progress and we have already
|
||||
@@ -496,6 +499,8 @@ static struct ioat_ring_ent **ioat2_alloc_ring(struct dma_chan *c, int order, gf
|
||||
return ring;
|
||||
}
|
||||
|
||||
+void ioat2_free_chan_resources(struct dma_chan *c);
|
||||
+
|
||||
/* ioat2_alloc_chan_resources - allocate/initialize ioat2 descriptor ring
|
||||
* @chan: channel to be initialized
|
||||
*/
|
||||
@@ -504,6 +509,7 @@ int ioat2_alloc_chan_resources(struct dma_chan *c)
|
||||
struct ioat2_dma_chan *ioat = to_ioat2_chan(c);
|
||||
struct ioat_chan_common *chan = &ioat->base;
|
||||
struct ioat_ring_ent **ring;
|
||||
+ u64 status;
|
||||
int order;
|
||||
|
||||
/* have we already been set up? */
|
||||
@@ -542,7 +548,20 @@ int ioat2_alloc_chan_resources(struct dma_chan *c)
|
||||
tasklet_enable(&chan->cleanup_task);
|
||||
ioat2_start_null_desc(ioat);
|
||||
|
||||
- return 1 << ioat->alloc_order;
|
||||
+ /* check that we got off the ground */
|
||||
+ udelay(5);
|
||||
+ status = ioat_chansts(chan);
|
||||
+ if (is_ioat_active(status) || is_ioat_idle(status)) {
|
||||
+ set_bit(IOAT_RUN, &chan->state);
|
||||
+ return 1 << ioat->alloc_order;
|
||||
+ } else {
|
||||
+ u32 chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
|
||||
+
|
||||
+ dev_WARN(to_dev(chan),
|
||||
+ "failed to start channel chanerr: %#x\n", chanerr);
|
||||
+ ioat2_free_chan_resources(c);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
}
|
||||
|
||||
bool reshape_ring(struct ioat2_dma_chan *ioat, int order)
|
||||
@@ -776,6 +795,7 @@ void ioat2_free_chan_resources(struct dma_chan *c)
|
||||
del_timer_sync(&chan->timer);
|
||||
device->cleanup_fn((unsigned long) c);
|
||||
device->reset_hw(chan);
|
||||
+ clear_bit(IOAT_RUN, &chan->state);
|
||||
|
||||
spin_lock_bh(&ioat->ring_lock);
|
||||
descs = ioat2_ring_space(ioat);
|
||||
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
|
||||
index 6740e31..52b1e3d 100644
|
||||
--- a/drivers/dma/ioat/dma_v3.c
|
||||
+++ b/drivers/dma/ioat/dma_v3.c
|
||||
@@ -401,7 +401,10 @@ static void ioat3_timer_event(unsigned long data)
|
||||
chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
|
||||
dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
|
||||
__func__, chanerr);
|
||||
- BUG_ON(is_ioat_bug(chanerr));
|
||||
+ if (test_bit(IOAT_RUN, &chan->state))
|
||||
+ BUG_ON(is_ioat_bug(chanerr));
|
||||
+ else /* we never got off the ground */
|
||||
+ return;
|
||||
}
|
||||
|
||||
/* if we haven't made progress and we have already
|
||||
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
|
||||
index 4173125..f4ba2e5 100644
|
||||
--- a/drivers/pci/intel-iommu.c
|
||||
+++ b/drivers/pci/intel-iommu.c
|
||||
@@ -3032,6 +3032,34 @@ static void __init iommu_exit_mempool(void)
|
||||
|
||||
}
|
||||
|
||||
+static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
|
||||
+{
|
||||
+ struct dmar_drhd_unit *drhd;
|
||||
+ u32 vtbar;
|
||||
+ int rc;
|
||||
+
|
||||
+ /* We know that this device on this chipset has its own IOMMU.
|
||||
+ * If we find it under a different IOMMU, then the BIOS is lying
|
||||
+ * to us. Hope that the IOMMU for this device is actually
|
||||
+ * disabled, and it needs no translation...
|
||||
+ */
|
||||
+ rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
|
||||
+ if (rc) {
|
||||
+ /* "can't" happen */
|
||||
+ dev_info(&pdev->dev, "failed to run vt-d quirk\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ vtbar &= 0xffff0000;
|
||||
+
|
||||
+ /* we know that the this iommu should be at offset 0xa000 from vtbar */
|
||||
+ drhd = dmar_find_matched_drhd_unit(pdev);
|
||||
+ if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
|
||||
+ TAINT_FIRMWARE_WORKAROUND,
|
||||
+ "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
|
||||
+ pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
|
||||
+}
|
||||
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
|
||||
+
|
||||
static void __init init_no_remapping_devices(void)
|
||||
{
|
||||
struct dmar_drhd_unit *drhd;
|
||||
--
|
||||
1.7.3.3
|
||||
|
@ -875,6 +875,8 @@ Patch13802: xfs-properly-account-for-reclaimed-inodes.patch
|
||||
|
||||
Patch13900: ima-allow-it-to-be-completely-disabled-and-default-off.patch
|
||||
|
||||
Patch13901: ioat2-catch-and-recover-from-broken-vtd-configurations.patch
|
||||
|
||||
%endif
|
||||
|
||||
BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
|
||||
@ -1673,6 +1675,9 @@ ApplyPatch xfs-properly-account-for-reclaimed-inodes.patch
|
||||
# disable IMA by default as we did in F-14
|
||||
ApplyPatch ima-allow-it-to-be-completely-disabled-and-default-off.patch
|
||||
|
||||
# rhbz605845 [556ab45f]
|
||||
ApplyPatch ioat2-catch-and-recover-from-broken-vtd-configurations.patch
|
||||
|
||||
# END OF PATCH APPLICATIONS
|
||||
|
||||
%endif
|
||||
@ -2294,6 +2299,10 @@ fi
|
||||
|
||||
|
||||
%changelog
|
||||
* Thu Dec 09 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- ioat2-catch-and-recover-from-broken-vtd-configurations.patch: copy patch
|
||||
from 2.6.35.y (#605845) [556ab45f]
|
||||
|
||||
* Thu Dec 09 2010 Kyle McMartin <kyle@redhat.com>
|
||||
- Copy tpm-fix-stall-on-boot.patch from rawhide tree. (#530393)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user