Commit 45687f96 authored by Alexandru Gagniuc's avatar Alexandru Gagniuc Committed by Bjorn Helgaas

PCI/AER: Don't clear AER bits if error handling is Firmware-First

If the platform requests Firmware-First error handling, firmware is
responsible for reading and clearing AER status bits.  If OSPM also clears
them, we may miss errors.  See ACPI v6.2, sec 18.3.2.5 and 18.4.

This race is mostly of theoretical significance, as it is not easy to
reasonably demonstrate it in testing.
Signed-off-by: default avatarAlexandru Gagniuc <mr.nuke.me@gmail.com>
[bhelgaas: add similar guards to pci_cleanup_aer_uncorrect_error_status()
and pci_aer_clear_fatal_status()]
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 944d5859
...@@ -397,6 +397,9 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) ...@@ -397,6 +397,9 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
if (!pos) if (!pos)
return -EIO; return -EIO;
if (pcie_aer_get_firmware_first(dev))
return -EIO;
/* Clear status bits for ERR_NONFATAL errors only */ /* Clear status bits for ERR_NONFATAL errors only */
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &sev); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &sev);
...@@ -417,6 +420,9 @@ void pci_aer_clear_fatal_status(struct pci_dev *dev) ...@@ -417,6 +420,9 @@ void pci_aer_clear_fatal_status(struct pci_dev *dev)
if (!pos) if (!pos)
return; return;
if (pcie_aer_get_firmware_first(dev))
return;
/* Clear status bits for ERR_FATAL errors only */ /* Clear status bits for ERR_FATAL errors only */
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &sev); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &sev);
...@@ -438,6 +444,9 @@ int pci_cleanup_aer_error_status_regs(struct pci_dev *dev) ...@@ -438,6 +444,9 @@ int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
if (!pos) if (!pos)
return -EIO; return -EIO;
if (pcie_aer_get_firmware_first(dev))
return -EIO;
port_type = pci_pcie_type(dev); port_type = pci_pcie_type(dev);
if (port_type == PCI_EXP_TYPE_ROOT_PORT) { if (port_type == PCI_EXP_TYPE_ROOT_PORT) {
pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &status); pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &status);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment