aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2016-10-03 10:42:57 -0400
committerBjorn Helgaas <bhelgaas@google.com>2016-10-03 10:42:57 -0400
commit4dc2db096a9f7c0316bafc18ee00d89e0acf4ebf (patch)
tree99563a111f0f5c0b2d8e90acfe840c7db1d0c603
parent9e18ad98ca71ca0cfcadf633547409829773f36a (diff)
parent6b20f728549030056402d7f68ea670eea1eb8198 (diff)
Merge branch 'pci/aer' into next
* pci/aer: PCI/AER: Fix aer_probe() kernel-doc comment PCI/AER: Cache capability position PCI/AER: Avoid memory allocation in interrupt handling path ACPI / APEI: Send correct severity to calculate AER severity PCI/AER: Remove duplicate AER severity translation PCI/AER: Remove aerdriver.forceload kernel parameter PCI/AER: Remove aerdriver.nosourceid kernel parameter x86/PCI: VMD: Add quirk for AER to ignore source ID PCI/AER: Add bus flag to skip source ID matching Conflicts: drivers/pci/probe.c
-rw-r--r--Documentation/PCI/pcieaer-howto.txt26
-rw-r--r--drivers/acpi/apei/ghes.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c18
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h9
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c61
-rw-r--r--drivers/pci/pcie/aer/aerdrv_errprint.c6
-rw-r--r--drivers/pci/probe.c5
-rw-r--r--drivers/pci/quirks.c17
-rw-r--r--include/linux/aer.h2
-rw-r--r--include/linux/pci.h10
10 files changed, 67 insertions, 89 deletions
diff --git a/Documentation/PCI/pcieaer-howto.txt b/Documentation/PCI/pcieaer-howto.txt
index b4987c0bcb20..ea8cafba255c 100644
--- a/Documentation/PCI/pcieaer-howto.txt
+++ b/Documentation/PCI/pcieaer-howto.txt
@@ -49,25 +49,17 @@ depends on CONFIG_PCIEPORTBUS, so pls. set CONFIG_PCIEPORTBUS=y and
49CONFIG_PCIEAER = y. 49CONFIG_PCIEAER = y.
50 50
512.2 Load PCI Express AER Root Driver 512.2 Load PCI Express AER Root Driver
52There is a case where a system has AER support in BIOS. Enabling the AER 52
53Root driver and having AER support in BIOS may result unpredictable 53Some systems have AER support in firmware. Enabling Linux AER support at
54behavior. To avoid this conflict, a successful load of the AER Root driver 54the same time the firmware handles AER may result in unpredictable
55requires ACPI _OSC support in the BIOS to allow the AER Root driver to 55behavior. Therefore, Linux does not handle AER events unless the firmware
56request for native control of AER. See the PCI FW 3.0 Specification for 56grants AER control to the OS via the ACPI _OSC method. See the PCI FW 3.0
57details regarding OSC usage. Currently, lots of firmwares don't provide 57Specification for details regarding _OSC usage.
58_OSC support while they use PCI Express. To support such firmwares,
59forceload, a parameter of type bool, could enable AER to continue to
60be initiated although firmwares have no _OSC support. To enable the
61walkaround, pls. add aerdriver.forceload=y to kernel boot parameter line
62when booting kernel. Note that forceload=n by default.
63
64nosourceid, another parameter of type bool, can be used when broken
65hardware (mostly chipsets) has root ports that cannot obtain the reporting
66source ID. nosourceid=n by default.
67 58
682.3 AER error output 592.3 AER error output
69When a PCI-E AER error is captured, an error message will be outputted to 60
70console. If it's a correctable error, it is outputted as a warning. 61When a PCIe AER error is captured, an error message will be output to
62console. If it's a correctable error, it is output as a warning.
71Otherwise, it is printed as an error. So users could choose different 63Otherwise, it is printed as an error. So users could choose different
72log level to filter out correctable error messages. 64log level to filter out correctable error messages.
73 65
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 60746ef904e4..f0a029e68d3e 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -457,7 +457,7 @@ static void ghes_do_proc(struct ghes *ghes,
457 457
458 devfn = PCI_DEVFN(pcie_err->device_id.device, 458 devfn = PCI_DEVFN(pcie_err->device_id.device,
459 pcie_err->device_id.function); 459 pcie_err->device_id.function);
460 aer_severity = cper_severity_to_aer(sev); 460 aer_severity = cper_severity_to_aer(gdata->error_severity);
461 461
462 /* 462 /*
463 * If firmware reset the component to contain 463 * If firmware reset the component to contain
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 49805a48b81c..139150b2bdfd 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -66,7 +66,7 @@ static int pcie_aer_disable;
66 66
67void pci_no_aer(void) 67void pci_no_aer(void)
68{ 68{
69 pcie_aer_disable = 1; /* has priority over 'forceload' */ 69 pcie_aer_disable = 1;
70} 70}
71 71
72bool pci_aer_available(void) 72bool pci_aer_available(void)
@@ -130,7 +130,7 @@ static void aer_enable_rootport(struct aer_rpc *rpc)
130 pcie_capability_clear_word(pdev, PCI_EXP_RTCTL, 130 pcie_capability_clear_word(pdev, PCI_EXP_RTCTL,
131 SYSTEM_ERROR_INTR_ON_MESG_MASK); 131 SYSTEM_ERROR_INTR_ON_MESG_MASK);
132 132
133 aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); 133 aer_pos = pdev->aer_cap;
134 /* Clear error status */ 134 /* Clear error status */
135 pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32); 135 pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32);
136 pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32); 136 pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32);
@@ -169,7 +169,7 @@ static void aer_disable_rootport(struct aer_rpc *rpc)
169 */ 169 */
170 set_downstream_devices_error_reporting(pdev, false); 170 set_downstream_devices_error_reporting(pdev, false);
171 171
172 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); 172 pos = pdev->aer_cap;
173 /* Disable Root's interrupt in response to error messages */ 173 /* Disable Root's interrupt in response to error messages */
174 pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, &reg32); 174 pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
175 reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK; 175 reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
@@ -196,7 +196,7 @@ irqreturn_t aer_irq(int irq, void *context)
196 unsigned long flags; 196 unsigned long flags;
197 int pos; 197 int pos;
198 198
199 pos = pci_find_ext_capability(pdev->port, PCI_EXT_CAP_ID_ERR); 199 pos = pdev->port->aer_cap;
200 /* 200 /*
201 * Must lock access to Root Error Status Reg, Root Error ID Reg, 201 * Must lock access to Root Error Status Reg, Root Error ID Reg,
202 * and Root error producer/consumer index 202 * and Root error producer/consumer index
@@ -290,7 +290,6 @@ static void aer_remove(struct pcie_device *dev)
290/** 290/**
291 * aer_probe - initialize resources 291 * aer_probe - initialize resources
292 * @dev: pointer to the pcie_dev data structure 292 * @dev: pointer to the pcie_dev data structure
293 * @id: pointer to the service id data structure
294 * 293 *
295 * Invoked when PCI Express bus loads AER service driver. 294 * Invoked when PCI Express bus loads AER service driver.
296 */ 295 */
@@ -300,11 +299,6 @@ static int aer_probe(struct pcie_device *dev)
300 struct aer_rpc *rpc; 299 struct aer_rpc *rpc;
301 struct device *device = &dev->device; 300 struct device *device = &dev->device;
302 301
303 /* Init */
304 status = aer_init(dev);
305 if (status)
306 return status;
307
308 /* Alloc rpc data structure */ 302 /* Alloc rpc data structure */
309 rpc = aer_alloc_rpc(dev); 303 rpc = aer_alloc_rpc(dev);
310 if (!rpc) { 304 if (!rpc) {
@@ -339,7 +333,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
339 u32 reg32; 333 u32 reg32;
340 int pos; 334 int pos;
341 335
342 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 336 pos = dev->aer_cap;
343 337
344 /* Disable Root's interrupt in response to error messages */ 338 /* Disable Root's interrupt in response to error messages */
345 pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, &reg32); 339 pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
@@ -392,7 +386,7 @@ static void aer_error_resume(struct pci_dev *dev)
392 pcie_capability_write_word(dev, PCI_EXP_DEVSTA, reg16); 386 pcie_capability_write_word(dev, PCI_EXP_DEVSTA, reg16);
393 387
394 /* Clean AER Root Error Status */ 388 /* Clean AER Root Error Status */
395 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 389 pos = dev->aer_cap;
396 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); 390 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
397 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); 391 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask);
398 if (dev->error_state == pci_channel_io_normal) 392 if (dev->error_state == pci_channel_io_normal)
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index 945c939a86c5..d51e4a57b190 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -60,6 +60,7 @@ struct aer_rpc {
60 struct pcie_device *rpd; /* Root Port device */ 60 struct pcie_device *rpd; /* Root Port device */
61 struct work_struct dpc_handler; 61 struct work_struct dpc_handler;
62 struct aer_err_source e_sources[AER_ERROR_SOURCES_MAX]; 62 struct aer_err_source e_sources[AER_ERROR_SOURCES_MAX];
63 struct aer_err_info e_info;
63 unsigned short prod_idx; /* Error Producer Index */ 64 unsigned short prod_idx; /* Error Producer Index */
64 unsigned short cons_idx; /* Error Consumer Index */ 65 unsigned short cons_idx; /* Error Consumer Index */
65 int isr; 66 int isr;
@@ -105,7 +106,6 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
105} 106}
106 107
107extern struct bus_type pcie_port_bus_type; 108extern struct bus_type pcie_port_bus_type;
108int aer_init(struct pcie_device *dev);
109void aer_isr(struct work_struct *work); 109void aer_isr(struct work_struct *work);
110void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); 110void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
111void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); 111void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info);
@@ -121,11 +121,4 @@ static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev)
121 return 0; 121 return 0;
122} 122}
123#endif 123#endif
124
125static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev,
126 int enable)
127{
128 pci_dev->__aer_firmware_first = !!enable;
129 pci_dev->__aer_firmware_first_valid = 1;
130}
131#endif /* _AERDRV_H_ */ 124#endif /* _AERDRV_H_ */
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 521e39c1b66d..b1303b32053f 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -27,11 +27,6 @@
27#include <linux/kfifo.h> 27#include <linux/kfifo.h>
28#include "aerdrv.h" 28#include "aerdrv.h"
29 29
30static bool forceload;
31static bool nosourceid;
32module_param(forceload, bool, 0);
33module_param(nosourceid, bool, 0);
34
35#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \ 30#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
36 PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE) 31 PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
37 32
@@ -40,7 +35,7 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev)
40 if (pcie_aer_get_firmware_first(dev)) 35 if (pcie_aer_get_firmware_first(dev))
41 return -EIO; 36 return -EIO;
42 37
43 if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) 38 if (!dev->aer_cap)
44 return -EIO; 39 return -EIO;
45 40
46 return pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS); 41 return pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
@@ -62,7 +57,7 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
62 int pos; 57 int pos;
63 u32 status; 58 u32 status;
64 59
65 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 60 pos = dev->aer_cap;
66 if (!pos) 61 if (!pos)
67 return -EIO; 62 return -EIO;
68 63
@@ -83,7 +78,7 @@ int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
83 if (!pci_is_pcie(dev)) 78 if (!pci_is_pcie(dev))
84 return -ENODEV; 79 return -ENODEV;
85 80
86 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 81 pos = dev->aer_cap;
87 if (!pos) 82 if (!pos)
88 return -EIO; 83 return -EIO;
89 84
@@ -102,6 +97,12 @@ int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
102 return 0; 97 return 0;
103} 98}
104 99
100int pci_aer_init(struct pci_dev *dev)
101{
102 dev->aer_cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
103 return pci_cleanup_aer_error_status_regs(dev);
104}
105
105/** 106/**
106 * add_error_device - list device to be handled 107 * add_error_device - list device to be handled
107 * @e_info: pointer to error info 108 * @e_info: pointer to error info
@@ -132,7 +133,8 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)
132 * When bus id is equal to 0, it might be a bad id 133 * When bus id is equal to 0, it might be a bad id
133 * reported by root port. 134 * reported by root port.
134 */ 135 */
135 if (!nosourceid && (PCI_BUS_NUM(e_info->id) != 0)) { 136 if ((PCI_BUS_NUM(e_info->id) != 0) &&
137 !(dev->bus->bus_flags & PCI_BUS_FLAGS_NO_AERSID)) {
136 /* Device ID match? */ 138 /* Device ID match? */
137 if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) 139 if (e_info->id == ((dev->bus->number << 8) | dev->devfn))
138 return true; 140 return true;
@@ -144,10 +146,10 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)
144 146
145 /* 147 /*
146 * When either 148 * When either
147 * 1) nosourceid==y; 149 * 1) bus id is equal to 0. Some ports might lose the bus
148 * 2) bus id is equal to 0. Some ports might lose the bus
149 * id of error source id; 150 * id of error source id;
150 * 3) There are multiple errors and prior id comparing fails; 151 * 2) bus flag PCI_BUS_FLAGS_NO_AERSID is set
152 * 3) There are multiple errors and prior ID comparing fails;
151 * We check AER status registers to find possible reporter. 153 * We check AER status registers to find possible reporter.
152 */ 154 */
153 if (atomic_read(&dev->enable_cnt) == 0) 155 if (atomic_read(&dev->enable_cnt) == 0)
@@ -158,7 +160,7 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)
158 if (!(reg16 & PCI_EXP_AER_FLAGS)) 160 if (!(reg16 & PCI_EXP_AER_FLAGS))
159 return false; 161 return false;
160 162
161 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 163 pos = dev->aer_cap;
162 if (!pos) 164 if (!pos)
163 return false; 165 return false;
164 166
@@ -555,7 +557,7 @@ static void handle_error_source(struct pcie_device *aerdev,
555 * Correctable error does not need software intervention. 557 * Correctable error does not need software intervention.
556 * No need to go through error recovery process. 558 * No need to go through error recovery process.
557 */ 559 */
558 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 560 pos = dev->aer_cap;
559 if (pos) 561 if (pos)
560 pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, 562 pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
561 info->status); 563 info->status);
@@ -647,7 +649,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
647 info->status = 0; 649 info->status = 0;
648 info->tlp_header_valid = 0; 650 info->tlp_header_valid = 0;
649 651
650 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 652 pos = dev->aer_cap;
651 653
652 /* The device might not support AER */ 654 /* The device might not support AER */
653 if (!pos) 655 if (!pos)
@@ -715,15 +717,8 @@ static inline void aer_process_err_devices(struct pcie_device *p_device,
715static void aer_isr_one_error(struct pcie_device *p_device, 717static void aer_isr_one_error(struct pcie_device *p_device,
716 struct aer_err_source *e_src) 718 struct aer_err_source *e_src)
717{ 719{
718 struct aer_err_info *e_info; 720 struct aer_rpc *rpc = get_service_data(p_device);
719 721 struct aer_err_info *e_info = &rpc->e_info;
720 /* struct aer_err_info might be big, so we allocate it with slab */
721 e_info = kmalloc(sizeof(struct aer_err_info), GFP_KERNEL);
722 if (!e_info) {
723 dev_printk(KERN_DEBUG, &p_device->port->dev,
724 "Can't allocate mem when processing AER errors\n");
725 return;
726 }
727 722
728 /* 723 /*
729 * There is a possibility that both correctable error and 724 * There is a possibility that both correctable error and
@@ -762,8 +757,6 @@ static void aer_isr_one_error(struct pcie_device *p_device,
762 if (find_source_device(p_device->port, e_info)) 757 if (find_source_device(p_device->port, e_info))
763 aer_process_err_devices(p_device, e_info); 758 aer_process_err_devices(p_device, e_info);
764 } 759 }
765
766 kfree(e_info);
767} 760}
768 761
769/** 762/**
@@ -812,19 +805,3 @@ void aer_isr(struct work_struct *work)
812 aer_isr_one_error(p_device, &e_src); 805 aer_isr_one_error(p_device, &e_src);
813 mutex_unlock(&rpc->rpc_mutex); 806 mutex_unlock(&rpc->rpc_mutex);
814} 807}
815
816/**
817 * aer_init - provide AER initialization
818 * @dev: pointer to AER pcie device
819 *
820 * Invoked when AER service driver is loaded.
821 */
822int aer_init(struct pcie_device *dev)
823{
824 if (forceload) {
825 dev_printk(KERN_DEBUG, &dev->device,
826 "aerdrv forceload requested.\n");
827 pcie_aer_force_firmware_first(dev->port, 0);
828 }
829 return 0;
830}
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 167fe411ce2e..54c4b691e51f 100644
--- a/drivers/pci/pcie/aer/aerdrv_errprint.c
+++ b/drivers/pci/pcie/aer/aerdrv_errprint.c
@@ -219,15 +219,13 @@ int cper_severity_to_aer(int cper_severity)
219} 219}
220EXPORT_SYMBOL_GPL(cper_severity_to_aer); 220EXPORT_SYMBOL_GPL(cper_severity_to_aer);
221 221
222void cper_print_aer(struct pci_dev *dev, int cper_severity, 222void cper_print_aer(struct pci_dev *dev, int aer_severity,
223 struct aer_capability_regs *aer) 223 struct aer_capability_regs *aer)
224{ 224{
225 int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0; 225 int layer, agent, status_strs_size, tlp_header_valid = 0;
226 u32 status, mask; 226 u32 status, mask;
227 const char **status_strs; 227 const char **status_strs;
228 228
229 aer_severity = cper_severity_to_aer(cper_severity);
230
231 if (aer_severity == AER_CORRECTABLE) { 229 if (aer_severity == AER_CORRECTABLE) {
232 status = aer->cor_status; 230 status = aer->cor_status;
233 mask = aer->cor_mask; 231 mask = aer->cor_mask;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e2e424472058..ab002671fa60 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1666,10 +1666,11 @@ static void pci_init_capabilities(struct pci_dev *dev)
1666 /* Enable ACS P2P upstream forwarding */ 1666 /* Enable ACS P2P upstream forwarding */
1667 pci_enable_acs(dev); 1667 pci_enable_acs(dev);
1668 1668
1669 pci_cleanup_aer_error_status_regs(dev);
1670
1671 /* Precision Time Measurement */ 1669 /* Precision Time Measurement */
1672 pci_ptm_init(dev); 1670 pci_ptm_init(dev);
1671
1672 /* Advanced Error Reporting */
1673 pci_aer_init(dev);
1673} 1674}
1674 1675
1675/* 1676/*
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 37ff0158e45f..6297942649bf 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4428,3 +4428,20 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev)
4428 } 4428 }
4429} 4429}
4430DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap); 4430DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap);
4431
4432/*
4433 * VMD-enabled root ports will change the source ID for all messages
4434 * to the VMD device. Rather than doing device matching with the source
4435 * ID, the AER driver should traverse the child device tree, reading
4436 * AER registers to find the faulting device.
4437 */
4438static void quirk_no_aersid(struct pci_dev *pdev)
4439{
4440 /* VMD Domain */
4441 if (pdev->bus->sysdata && pci_domain_nr(pdev->bus) >= 0x10000)
4442 pdev->bus->bus_flags |= PCI_BUS_FLAGS_NO_AERSID;
4443}
4444DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2030, quirk_no_aersid);
4445DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2031, quirk_no_aersid);
4446DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2032, quirk_no_aersid);
4447DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid);
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 164049357e5c..04602cbe85dc 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -63,7 +63,7 @@ static inline int pci_cleanup_aer_error_status_regs(struct pci_dev *dev)
63} 63}
64#endif 64#endif
65 65
66void cper_print_aer(struct pci_dev *dev, int cper_severity, 66void cper_print_aer(struct pci_dev *dev, int aer_severity,
67 struct aer_capability_regs *aer); 67 struct aer_capability_regs *aer);
68int cper_severity_to_aer(int cper_severity); 68int cper_severity_to_aer(int cper_severity);
69void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, 69void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 7256f33b6a15..84d222ad3c08 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -187,8 +187,9 @@ enum pci_irq_reroute_variant {
187 187
188typedef unsigned short __bitwise pci_bus_flags_t; 188typedef unsigned short __bitwise pci_bus_flags_t;
189enum pci_bus_flags { 189enum pci_bus_flags {
190 PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1, 190 PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1,
191 PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2, 191 PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2,
192 PCI_BUS_FLAGS_NO_AERSID = (__force pci_bus_flags_t) 4,
192}; 193};
193 194
194/* These values come from the PCI Express Spec */ 195/* These values come from the PCI Express Spec */
@@ -268,6 +269,9 @@ struct pci_dev {
268 unsigned int class; /* 3 bytes: (base,sub,prog-if) */ 269 unsigned int class; /* 3 bytes: (base,sub,prog-if) */
269 u8 revision; /* PCI revision, low byte of class word */ 270 u8 revision; /* PCI revision, low byte of class word */
270 u8 hdr_type; /* PCI header type (`multi' flag masked out) */ 271 u8 hdr_type; /* PCI header type (`multi' flag masked out) */
272#ifdef CONFIG_PCIEAER
273 u16 aer_cap; /* AER capability offset */
274#endif
271 u8 pcie_cap; /* PCIe capability offset */ 275 u8 pcie_cap; /* PCIe capability offset */
272 u8 msi_cap; /* MSI capability offset */ 276 u8 msi_cap; /* MSI capability offset */
273 u8 msix_cap; /* MSI-X capability offset */ 277 u8 msix_cap; /* MSI-X capability offset */
@@ -1374,9 +1378,11 @@ static inline bool pcie_aspm_support_enabled(void) { return false; }
1374#ifdef CONFIG_PCIEAER 1378#ifdef CONFIG_PCIEAER
1375void pci_no_aer(void); 1379void pci_no_aer(void);
1376bool pci_aer_available(void); 1380bool pci_aer_available(void);
1381int pci_aer_init(struct pci_dev *dev);
1377#else 1382#else
1378static inline void pci_no_aer(void) { } 1383static inline void pci_no_aer(void) { }
1379static inline bool pci_aer_available(void) { return false; } 1384static inline bool pci_aer_available(void) { return false; }
1385static inline int pci_aer_init(struct pci_dev *d) { return -ENODEV; }
1380#endif 1386#endif
1381 1387
1382#ifdef CONFIG_PCIE_ECRC 1388#ifdef CONFIG_PCIE_ECRC