xhci: harden xhci_find_next_ext_cap against device removal
xhci_find_next_ext_cap doesn't check for PCI hotplug removal and may use
the PCI master abort bit pattern (~0) to calculate a new PCI address
offset to read/write. The has lead to reproducable crashes when testing
surprise removal during device initialization on a Stratus platform, at
least after commit d5ddcdf4d6
("xhci: rework xhci extended capability
list parsing functions").
The crash is repeatable on a Stratus platform when injecting hardware
faults to induce xHCI host controller hotplug during driver
initialization. If a PCI read in xhci_find_next_ext_cap returns the
master abort pattern, quirk_usb_handoff_xhci may start using a bogus
ext_cap_offset to start searching more bogus PCI addresses.
Signed-off-by: Joe Lawrence <joe.lawrence@stratus.com>
Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
207b08b942
commit
89140fdaf1
@ -112,12 +112,16 @@ static inline int xhci_find_next_ext_cap(void __iomem *base, u32 start, int id)
|
||||
offset = start;
|
||||
if (!start || start == XHCI_HCC_PARAMS_OFFSET) {
|
||||
val = readl(base + XHCI_HCC_PARAMS_OFFSET);
|
||||
if (val == ~0)
|
||||
return 0;
|
||||
offset = XHCI_HCC_EXT_CAPS(val) << 2;
|
||||
if (!offset)
|
||||
return 0;
|
||||
};
|
||||
do {
|
||||
val = readl(base + offset);
|
||||
if (val == ~0)
|
||||
return 0;
|
||||
if (XHCI_EXT_CAPS_ID(val) == id && offset != start)
|
||||
return offset;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user