linux/arch/s390
Heiko Carstens 82d3edb50a s390/cpum_sf: add READ_ONCE() semantics to compare and swap loops
The current cmpxchg_double() loops within the perf hw sampling code do not
have READ_ONCE() semantics to read the old value from memory. This allows
the compiler to generate code which reads the "old" value several times
from memory, which again allows for inconsistencies.

For example:

        /* Reset trailer (using compare-double-and-swap) */
        do {
                te_flags = te->flags & ~SDB_TE_BUFFER_FULL_MASK;
                te_flags |= SDB_TE_ALERT_REQ_MASK;
        } while (!cmpxchg_double(&te->flags, &te->overflow,
                 te->flags, te->overflow,
                 te_flags, 0ULL));

The compiler could generate code where te->flags used within the
cmpxchg_double() call may be refetched from memory and which is not
necessarily identical to the previous read version which was used to
generate te_flags. Which in turn means that an incorrect update could
happen.

Fix this by adding READ_ONCE() semantics to all cmpxchg_double()
loops. Given that READ_ONCE() cannot generate code on s390 which atomically
reads 16 bytes, use a private compare-and-swap-double implementation to
achieve that.

Also replace cmpxchg_double() with the private implementation to be able to
re-use the old value within the loops.

As a side effect this converts the whole code to only use bit fields
to read and modify bits within the hws trailer header.

Reported-by: Alexander Gordeev <agordeev@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Acked-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.ibm.com>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/linux-s390/Y71QJBhNTIatvxUT@osiris/T/#ma14e2a5f7aa8ed4b94b6f9576799b3ad9c60f333
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
2023-01-11 15:28:34 +01:00
..
appldata s390/appldata: remove power management callbacks 2022-12-02 18:25:04 +01:00
boot s390: fix -Wundef warning for CONFIG_KERNEL_ZSTD 2023-01-09 14:30:36 +01:00
configs random: use random.trust_{bootloader,cpu} command line option only 2022-11-18 02:18:10 +01:00
crypto crypto: Kconfig - simplify cipher entries 2022-08-26 18:50:43 +08:00
hypfs s390/hypfs: remove unused info_blk_hdr__pcpus() function 2022-11-23 16:24:07 +01:00
include s390/cpum_sf: add READ_ONCE() semantics to compare and swap loops 2023-01-11 15:28:34 +01:00
kernel s390/cpum_sf: add READ_ONCE() semantics to compare and swap loops 2023-01-11 15:28:34 +01:00
kvm IOMMU Updates for Linux v6.2 2022-12-19 08:34:39 -06:00
lib s390/uaccess: add missing EX_TABLE entries to __clear_user() 2022-10-26 14:47:30 +02:00
mm ARM64: 2022-12-15 11:12:21 -08:00
net s390/bpf: Fix typo in comment 2022-05-23 11:25:53 -07:00
pci IOMMU Updates for Linux v6.2 2022-12-19 08:34:39 -06:00
purgatory s390/purgatory: remove duplicated build rule of kexec-purgatory.o 2022-06-30 14:18:16 +02:00
tools KVM: s390: Add facility 197 to the allow list 2022-07-13 15:25:25 +02:00
Kbuild
Kconfig s390 updates for 6.2 merge window 2022-12-12 11:04:08 -08:00
Kconfig.debug s390/Kconfig.debug: fix indentation 2022-06-01 12:03:15 +02:00
Makefile s390: always build relocatable kernel 2022-11-08 19:32:32 +01:00