]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
PCI: ARI is a PCIe v2 feature
authorChris Wright <chrisw@sous-sol.org>
Wed, 13 Jul 2011 17:14:33 +0000 (10:14 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 8 Aug 2011 17:23:12 +0000 (10:23 -0700)
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

index 0d3326ddd5c1c0e9ac6ac317f93ecb7267a7091a..6f8352c42d3ee733da725d574a14e176fceb7407 100644 (file)
@@ -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;