lkml.org 
[lkml]   [2021]   [Mar]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.11 06/52] scsi: ufs: Introduce a quirk to allow only page-aligned sg entries
    Date
    From: Kiwoong Kim <kwmad.kim@samsung.com>

    [ Upstream commit 2b2bfc8aa519f696087475ed8e8c61850c673272 ]

    Some SoCs require a single scatterlist entry for smaller than page size,
    i.e. 4KB. When dispatching commands with more than one scatterlist entry
    under 4KB in size the following behavior is observed:

    A command to read a block range is dispatched with two scatterlist entries
    that are named AAA and BBB. After dispatching, the host builds two PRDT
    entries and during transmission, device sends just one DATA IN because
    device doesn't care about host DMA. The host then transfers the combined
    amount of data from start address of the area named AAA. As a consequence,
    the area that follows AAA in memory would be corrupted.

    |<------------->|
    +-------+------------ +-------+
    + AAA + (corrupted) ... + BBB +
    +-------+------------ +-------+

    To avoid this we need to enforce page size alignment for sg entries.

    Link: https://lore.kernel.org/r/56dddef94f60bd9466fd77e69f64bbbd657ed2a1.1611026909.git.kwmad.kim@samsung.com
    Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/scsi/ufs/ufshcd.c | 2 ++
    drivers/scsi/ufs/ufshcd.h | 4 ++++
    2 files changed, 6 insertions(+)

    diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
    index 48cbd4f294dd..3ab1702e5b04 100644
    --- a/drivers/scsi/ufs/ufshcd.c
    +++ b/drivers/scsi/ufs/ufshcd.c
    @@ -4829,6 +4829,8 @@ static int ufshcd_slave_configure(struct scsi_device *sdev)
    struct request_queue *q = sdev->request_queue;

    blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1);
    + if (hba->quirks & UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE)
    + blk_queue_update_dma_alignment(q, PAGE_SIZE - 1);

    if (ufshcd_is_rpm_autosuspend_allowed(hba))
    sdev->rpm_autosuspend = 1;
    diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
    index 85f9d0fbfbd9..8cb64ae95462 100644
    --- a/drivers/scsi/ufs/ufshcd.h
    +++ b/drivers/scsi/ufs/ufshcd.h
    @@ -557,6 +557,10 @@ enum ufshcd_quirks {
    */
    UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING = 1 << 13,

    + /*
    + * This quirk allows only sg entries aligned with page size.
    + */
    + UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE = 1 << 13,
    };

    enum ufshcd_caps {
    --
    2.30.1
    \
     
     \ /
      Last update: 2021-03-02 17:09    [W:4.705 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site