]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.32.12/pci-fix-nested-spinlock-hang-in-aer_inject.patch
Fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 2.6.32.12 / pci-fix-nested-spinlock-hang-in-aer_inject.patch
CommitLineData
3ababc44
GKH
1From bd1f46deba615971a58193afd0202878cadf19a7 Mon Sep 17 00:00:00 2001
2From: Andrew Patterson <andrew.patterson@hp.com>
3Date: Fri, 22 Jan 2010 14:06:53 -0700
4Subject: PCI: fix nested spinlock hang in aer_inject
5
6From: Andrew Patterson <andrew.patterson@hp.com>
7
8commit bd1f46deba615971a58193afd0202878cadf19a7 upstream.
9
10The aer_inject module hangs in aer_inject() when checking the device's
11error masks. The hang is due to a recursive use of the aer_inject lock.
12The aer_inject() routine grabs the lock while processing the error and then
13calls pci_read_config_dword to read the masks. The pci_read_config_dword
14routine is earlier overridden by pci_read_aer, which among other things,
15grabs the aer_inject lock.
16
17Fixed by moving the pci_read_config_dword calls to read the masks to before
18the lock is taken.
19
20Acked-by: Huang Ying <ying.huang@intel.com>
21Signed-off-by: Andrew Patterson <andrew.patterson@hp.com>
22Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
23Cc: maximilian attems <max@stro.at>
24Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
25
26---
27 drivers/pci/pcie/aer/aer_inject.c | 12 ++++++------
28 1 file changed, 6 insertions(+), 6 deletions(-)
29
30--- a/drivers/pci/pcie/aer/aer_inject.c
31+++ b/drivers/pci/pcie/aer/aer_inject.c
32@@ -302,7 +302,7 @@ static int aer_inject(struct aer_error_i
33 unsigned long flags;
34 unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn);
35 int pos_cap_err, rp_pos_cap_err;
36- u32 sever, mask;
37+ u32 sever, cor_mask, uncor_mask;
38 int ret = 0;
39
40 dev = pci_get_bus_and_slot(einj->bus, devfn);
41@@ -320,6 +320,9 @@ static int aer_inject(struct aer_error_i
42 goto out_put;
43 }
44 pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever);
45+ pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &cor_mask);
46+ pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK,
47+ &uncor_mask);
48
49 rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR);
50 if (!rp_pos_cap_err) {
51@@ -354,17 +357,14 @@ static int aer_inject(struct aer_error_i
52 err->header_log2 = einj->header_log2;
53 err->header_log3 = einj->header_log3;
54
55- pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &mask);
56- if (einj->cor_status && !(einj->cor_status & ~mask)) {
57+ if (einj->cor_status && !(einj->cor_status & ~cor_mask)) {
58 ret = -EINVAL;
59 printk(KERN_WARNING "The correctable error(s) is masked "
60 "by device\n");
61 spin_unlock_irqrestore(&inject_lock, flags);
62 goto out_put;
63 }
64-
65- pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, &mask);
66- if (einj->uncor_status && !(einj->uncor_status & ~mask)) {
67+ if (einj->uncor_status && !(einj->uncor_status & ~uncor_mask)) {
68 ret = -EINVAL;
69 printk(KERN_WARNING "The uncorrectable error(s) is masked "
70 "by device\n");