lkml.org 
[lkml]   [2022]   [Aug]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.19 0998/1157] powerpc/iommu: Fix iommu_table_in_use for a small default DMA window case
    Date
    From: Alexey Kardashevskiy <aik@ozlabs.ru>

    [ Upstream commit d80f6de9d601c30b53c17f00cb7cfe3169f2ddad ]

    The existing iommu_table_in_use() helper checks if the kernel is using
    any of TCEs. There are some reserved TCEs:
    1) the very first one if DMA window starts from 0 to avoid having a zero
    but still valid DMA handle;
    2) it_reserved_start..it_reserved_end to exclude MMIO32 window in case
    the default window spans across that - this is the default for the first
    DMA window on PowerNV.

    When 1) is the case and 2) is not the helper does not skip 1) and returns
    wrong status.

    This only seems occurring when passing through a PCI device to a nested
    guest (not something we support really well) so it has not been seen
    before.

    This fixes the bug by adding a special case for no MMIO32 reservation.

    Fixes: 3c33066a2190 ("powerpc/kernel/iommu: Add new iommu_table_in_use() helper")
    Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20220714081119.3714605-1-aik@ozlabs.ru
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/powerpc/kernel/iommu.c | 5 +++++
    1 file changed, 5 insertions(+)

    diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
    index 7e56ddb3e0b9..caebe1431596 100644
    --- a/arch/powerpc/kernel/iommu.c
    +++ b/arch/powerpc/kernel/iommu.c
    @@ -775,6 +775,11 @@ bool iommu_table_in_use(struct iommu_table *tbl)
    /* ignore reserved bit0 */
    if (tbl->it_offset == 0)
    start = 1;
    +
    + /* Simple case with no reserved MMIO32 region */
    + if (!tbl->it_reserved_start && !tbl->it_reserved_end)
    + return find_next_bit(tbl->it_map, tbl->it_size, start) != tbl->it_size;
    +
    end = tbl->it_reserved_start - tbl->it_offset;
    if (find_next_bit(tbl->it_map, end, start) != end)
    return true;
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-08-16 06:53    [W:4.289 / U:0.120 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site