--- /dev/null
+From 6cdfd995a65a52e05b99e3a72a9b979abe73b312 Mon Sep 17 00:00:00 2001
+From: Andrew Patterson <andrew.patterson@hp.com>
+Date: Thu, 3 Dec 2009 10:28:20 -0700
+Subject: PCI: unconditionally clear AER uncorr status register during cleanup
+
+From: Andrew Patterson <andrew.patterson@hp.com>
+
+commit 6cdfd995a65a52e05b99e3a72a9b979abe73b312 upstream.
+
+The current implementation of pci_cleanup_aer_uncorrect_error_status
+only clears either fatal or non-fatal error status bits depending
+on the state of the I/O channel. This implementation will then often
+leave some bits set after PCI error recovery completes. The uncleared bit
+settings will then be falsely reported the next time an AER interrupt is
+generated for that hierarchy. An easy way to illustrate this issue is to
+use the aer-inject module to simultaneously inject both an uncorrectable
+non-fatal and uncorrectable fatal error. One of the errors will not be
+cleared.
+
+This patch resolves this issue by unconditionally clearing all bits in
+the AER uncorrectable status register. All settings and corrective action
+strategies are saved and determined before
+pci_cleanup_aer_uncorrect_error_status is called, so this change should not
+affect errory handling functionality.
+
+Signed-off-by: Andrew Patterson <andrew.patterson@hp.com>
+Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Cc: Alex Chiang <achiang@hp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/pcie/aer/aerdrv_core.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+--- a/drivers/pci/pcie/aer/aerdrv_core.c
++++ b/drivers/pci/pcie/aer/aerdrv_core.c
+@@ -78,19 +78,15 @@ EXPORT_SYMBOL_GPL(pci_disable_pcie_error
+ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
+ {
+ int pos;
+- u32 status, mask;
++ u32 status;
+
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+ if (!pos)
+ return -EIO;
+
+ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
+- pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask);
+- if (dev->error_state == pci_channel_io_normal)
+- status &= ~mask; /* Clear corresponding nonfatal bits */
+- else
+- status &= mask; /* Clear corresponding fatal bits */
+- pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
++ if (status)
++ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
+
+ return 0;
+ }