• Lorenzo Pieralisi's avatar
    arm64: cmpxchg_dbl: fix return value type · 57a65667
    Lorenzo Pieralisi authored
    The current arm64 __cmpxchg_double{_mb} implementations carry out the
    compare exchange by first comparing the old values passed in to the
    values read from the pointer provided and by stashing the cumulative
    bitwise difference in a 64-bit register.
    
    By comparing the register content against 0, it is possible to detect if
    the values read differ from the old values passed in, so that the compare
    exchange detects whether it has to bail out or carry on completing the
    operation with the exchange.
    
    Given the current implementation, to detect the cmpxchg operation
    status, the __cmpxchg_double{_mb} functions should return the 64-bit
    stashed bitwise difference so that the caller can detect cmpxchg failure
    by comparing the return value content against 0. The current implementation
    declares the return value as an int, which means that the 64-bit
    value stashing the bitwise difference is truncated before being
    returned to the __cmpxchg_double{_mb} callers, which means that
    any bitwise difference present in the top 32 bits goes undetected,
    triggering false positives and subsequent kernel failures.
    
    This patch fixes the issue by declaring the arm64 __cmpxchg_double{_mb}
    return values as a long, so that the bitwise difference is
    properly propagated on failure, restoring the expected behaviour.
    
    Fixes: e9a4b795 ("arm64: cmpxchg_dbl: patch in lse instructions when supported by the CPU")
    Cc: <stable@vger.kernel.org> # 4.3+
    Cc: Marc Zyngier <marc.zyngier@arm.com>
    Acked-by: default avatarWill Deacon <will.deacon@arm.com>
    Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
    Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    57a65667
atomic_lse.h 11 KB