lkml.org 
[lkml]   [2022]   [Jan]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 29/37] usb: mtu3: add memory barrier before set GPDs HWO
    Date
    From: Chunfeng Yun <chunfeng.yun@mediatek.com>

    commit a7aae769ca626819a7f9f078ebdc69a8a1b00c81 upstream.

    There is a seldom issue that the controller access invalid address
    and trigger devapc or emimpu violation. That is due to memory access
    is out of order and cause gpd data is not correct.
    Add mb() to prohibit compiler or cpu from reordering to make sure GPD
    is fully written before setting its HWO.

    Fixes: 48e0d3735aa5 ("usb: mtu3: supports new QMU format")
    Cc: stable@vger.kernel.org
    Reported-by: Eddie Hung <eddie.hung@mediatek.com>
    Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
    Link: https://lore.kernel.org/r/20211218095749.6250-2-chunfeng.yun@mediatek.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/usb/mtu3/mtu3_qmu.c | 7 ++++++-
    1 file changed, 6 insertions(+), 1 deletion(-)

    --- a/drivers/usb/mtu3/mtu3_qmu.c
    +++ b/drivers/usb/mtu3/mtu3_qmu.c
    @@ -273,6 +273,8 @@ static int mtu3_prepare_tx_gpd(struct mt
    gpd->dw3_info |= cpu_to_le32(GPD_EXT_FLAG_ZLP);
    }

    + /* prevent reorder, make sure GPD's HWO is set last */
    + mb();
    gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_IOC | GPD_FLAGS_HWO);

    mreq->gpd = gpd;
    @@ -306,6 +308,8 @@ static int mtu3_prepare_rx_gpd(struct mt
    gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma));
    ext_addr |= GPD_EXT_NGP(mtu, upper_32_bits(enq_dma));
    gpd->dw3_info = cpu_to_le32(ext_addr);
    + /* prevent reorder, make sure GPD's HWO is set last */
    + mb();
    gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_IOC | GPD_FLAGS_HWO);

    mreq->gpd = gpd;
    @@ -445,7 +449,8 @@ static void qmu_tx_zlp_error_handler(str
    return;
    }
    mtu3_setbits(mbase, MU3D_EP_TXCR0(mep->epnum), TX_TXPKTRDY);
    -
    + /* prevent reorder, make sure GPD's HWO is set last */
    + mb();
    /* by pass the current GDP */
    gpd_current->dw0_info |= cpu_to_le32(GPD_FLAGS_BPS | GPD_FLAGS_HWO);


    \
     
     \ /
      Last update: 2022-01-03 15:29    [W:4.080 / U:0.360 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site