• Robin Murphy's avatar
    iommu/io-pgtable-arm: Fix race handling in split_blk_unmap() · 85c7a0f1
    Robin Murphy authored
    In removing the pagetable-wide lock, we gained the possibility of the
    vanishingly unlikely case where we have a race between two concurrent
    unmappers splitting the same block entry. The logic to handle this is
    fairly straightforward - whoever loses the race frees their partial
    next-level table and instead dereferences the winner's newly-installed
    entry in order to fall back to a regular unmap, which intentionally
    echoes the pre-existing case of recursively splitting a 1GB block down
    to 4KB pages by installing a full table of 2MB blocks first.
    
    Unfortunately, the chump who implemented that logic failed to update the
    condition check for that fallback, meaning that if said race occurs at
    the last level (where the loser's unmap_idx is valid) then the unmap
    won't actually happen. Fix that to properly account for both the race
    and recursive cases.
    
    Fixes: 2c3d273e ("iommu/io-pgtable-arm: Support lockless operation")
    Signed-off-by: default avatarRobin Murphy <robin.murphy@arm.com>
    [will: re-jig control flow to avoid duplicate cmpxchg test]
    Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
    85c7a0f1
io-pgtable-arm.c 30.8 KB