| From 864d296cf948aef0fa32b81407541572583f7572 Mon Sep 17 00:00:00 2001 |
| From: Chris Wright <chrisw@sous-sol.org> |
| Date: Wed, 13 Jul 2011 10:14:33 -0700 |
| Subject: PCI: ARI is a PCIe v2 feature |
| |
| From: Chris Wright <chrisw@sous-sol.org> |
| |
| commit 864d296cf948aef0fa32b81407541572583f7572 upstream. |
| |
| The function pci_enable_ari() may mistakenly set the downstream port |
| of a v1 PCIe switch in ARI Forwarding mode. This is a PCIe v2 feature, |
| and with an SR-IOV device on that switch port believing the switch above |
| is ARI capable it may attempt to use functions 8-255, translating into |
| invalid (non-zero) device numbers for that bus. This has been seen |
| to cause Completion Timeouts and general misbehaviour including hangs |
| and panics. |
| |
| Acked-by: Don Dutile <ddutile@redhat.com> |
| Tested-by: Don Dutile <ddutile@redhat.com> |
| Signed-off-by: Chris Wright <chrisw@sous-sol.org> |
| Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/pci/pci.c | 7 ++++++- |
| 1 file changed, 6 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/pci/pci.c |
| +++ b/drivers/pci/pci.c |
| @@ -1507,7 +1507,7 @@ void pci_enable_ari(struct pci_dev *dev) |
| { |
| int pos; |
| u32 cap; |
| - u16 ctrl; |
| + u16 flags, ctrl; |
| struct pci_dev *bridge; |
| |
| if (!dev->is_pcie || dev->devfn) |
| @@ -1525,6 +1525,11 @@ void pci_enable_ari(struct pci_dev *dev) |
| if (!pos) |
| return; |
| |
| + /* ARI is a PCIe v2 feature */ |
| + pci_read_config_word(bridge, pos + PCI_EXP_FLAGS, &flags); |
| + if ((flags & PCI_EXP_FLAGS_VERS) < 2) |
| + return; |
| + |
| pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap); |
| if (!(cap & PCI_EXP_DEVCAP2_ARI)) |
| return; |