| From b49bfd32901625e4adcfee011d2b32a43b4db67d Mon Sep 17 00:00:00 2001 |
| From: Youquan Song <youquan.song@linux.intel.com> |
| Date: Thu, 17 Dec 2009 08:22:48 -0500 |
| Subject: PCIe AER: prevent AER injection if hardware masks error reporting |
| |
| From: Youquan Song <youquan.song@linux.intel.com> |
| |
| commit b49bfd32901625e4adcfee011d2b32a43b4db67d upstream. |
| |
| The Correcteable/Uncorrectable Error Mask Registers are used by PCIe AER |
| driver which will controls the reporting of individual errors to PCIe RC |
| via PCIe error messages. |
| |
| If hardware masks special error reporting to RC, the aer_inject driver |
| should not inject aer error. |
| |
| Acked-by: Andi Kleen <ak@linux.intel.com> |
| Signed-off-by: Youquan Song <youquan.song@intel.com> |
| Acked-by: Ying Huang <ying.huang@intel.com> |
| Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> |
| Cc: maximilian attems <max@stro.at> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/pci/pcie/aer/aer_inject.c | 20 +++++++++++++++++++- |
| 1 file changed, 19 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/pci/pcie/aer/aer_inject.c |
| +++ b/drivers/pci/pcie/aer/aer_inject.c |
| @@ -302,7 +302,7 @@ static int aer_inject(struct aer_error_i |
| unsigned long flags; |
| unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); |
| int pos_cap_err, rp_pos_cap_err; |
| - u32 sever; |
| + u32 sever, mask; |
| int ret = 0; |
| |
| dev = pci_get_bus_and_slot(einj->bus, devfn); |
| @@ -354,6 +354,24 @@ static int aer_inject(struct aer_error_i |
| err->header_log2 = einj->header_log2; |
| err->header_log3 = einj->header_log3; |
| |
| + pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &mask); |
| + if (einj->cor_status && !(einj->cor_status & ~mask)) { |
| + ret = -EINVAL; |
| + printk(KERN_WARNING "The correctable error(s) is masked " |
| + "by device\n"); |
| + spin_unlock_irqrestore(&inject_lock, flags); |
| + goto out_put; |
| + } |
| + |
| + pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, &mask); |
| + if (einj->uncor_status && !(einj->uncor_status & ~mask)) { |
| + ret = -EINVAL; |
| + printk(KERN_WARNING "The uncorrectable error(s) is masked " |
| + "by device\n"); |
| + spin_unlock_irqrestore(&inject_lock, flags); |
| + goto out_put; |
| + } |
| + |
| rperr = __find_aer_error_by_dev(rpdev); |
| if (!rperr) { |
| rperr = rperr_alloc; |