The VIA VL805 host controller is well-known for causing problems on
systems with IOMMUs enabled, ranging from triggering endless streams of
fault messages to locking itself up completely. It appears that the root
of the problem might be an over-aggressive prefetching of TRBs, wherein
consuming commands near the end of a queue segment causes it to read off
the end of the segment, even across a page boundary. This blows up when
DMA mapping ops are backed by an IOMMU, since there is no guarantee that
addresses outside the allocated segment are accessible at all.
Some trial-and-error investigation reveals that we can avoid such
cross-page reads by not using the last few TRBs in a segment; to that
end, factor out the implicit index of the end-of-segemnt link TRB, and
implement a quirk to move it slightly further forward when necessary.
Signed-off-by: Robin Murphy <robin.murphy@xxxxxxx>
---
drivers/usb/host/xhci-mem.c | 32 +++++++++++++++++++-------------
drivers/usb/host/xhci-pci.c | 5 +++++
drivers/usb/host/xhci-ring.c | 10 +++++++++-
drivers/usb/host/xhci.c | 10 +++++-----
drivers/usb/host/xhci.h | 2 ++
5 files changed, 40 insertions(+), 19 deletions(-)