]> git.itanic.dy.fi Git - linux-stable/commitdiff
xhci: Fix TRB prefetch issue of ZHAOXIN hosts
authorWeitao Wang <WeitaoWang-oc@zhaoxin.com>
Fri, 2 Jun 2023 14:40:07 +0000 (17:40 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 23 Jul 2023 11:47:54 +0000 (13:47 +0200)
commit 2a865a652299f5666f3b785cbe758c5f57453036 upstream.

On some ZHAOXIN hosts, xHCI will prefetch TRB for performance
improvement. However this TRB prefetch mechanism may cross page boundary,
which may access memory not allocated by xHCI driver. In order to fix
this issue, two pages was allocated for a segment and only the first
page will be used. And add a quirk XHCI_ZHAOXIN_TRB_FETCH for this issue.

Cc: stable@vger.kernel.org
Signed-off-by: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Message-ID: <20230602144009.1225632-10-mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci.h

index 9d9ab7e3560a2eb3bada23fb49e78ad467852bd3..814599e688138648e2178805e03eeab8663849a6 100644 (file)
@@ -2454,8 +2454,12 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
         * and our use of dma addresses in the trb_address_map radix tree needs
         * TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need.
         */
-       xhci->segment_pool = dma_pool_create("xHCI ring segments", dev,
-                       TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size);
+       if (xhci->quirks & XHCI_ZHAOXIN_TRB_FETCH)
+               xhci->segment_pool = dma_pool_create("xHCI ring segments", dev,
+                               TRB_SEGMENT_SIZE * 2, TRB_SEGMENT_SIZE * 2, xhci->page_size * 2);
+       else
+               xhci->segment_pool = dma_pool_create("xHCI ring segments", dev,
+                               TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size);
 
        /* See Table 46 and Note on Figure 55 */
        xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev,
index 632f85575d1de8b0ab293cd12c1efebc3f269ead..7bb6c42297773f791264554ed2e5364e2703518f 100644 (file)
@@ -337,8 +337,13 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
                xhci->quirks |= XHCI_NO_SOFT_RETRY;
 
        if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) {
-               if (pdev->device == 0x9202)
+               if (pdev->device == 0x9202) {
                        xhci->quirks |= XHCI_RESET_ON_RESUME;
+                       xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH;
+               }
+
+               if (pdev->device == 0x9203)
+                       xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH;
        }
 
        /* xHC spec requires PCI devices to support D3hot and D3cold */
index 0b22e858086379f6ba346775311833126eaab4d4..0e145716019eb91b821a124261e41ef293413e58 100644 (file)
@@ -1906,6 +1906,7 @@ struct xhci_hcd {
 #define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(42)
 #define XHCI_SUSPEND_RESUME_CLKS       BIT_ULL(43)
 #define XHCI_RESET_TO_DEFAULT  BIT_ULL(44)
+#define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)
 
        unsigned int            num_active_eps;
        unsigned int            limit_active_eps;