Files
linux/arch/s390/include/asm/word-at-a-time.h
Heiko Carstens 37540b8c28 s390: Revert support for DCACHE_WORD_ACCESS
load_unaligned_zeropad() reads eight bytes from unaligned addresses and may
cross page boundaries. It handles exceptions which may happen if reading
from the second page results in an exception.

For pages which are donated to the Ultravisor for secure execution purposes
the do_secure_storage_access() exception handler however does not handle
such exceptions correctly. Such an exception may result in an endless
exception loop which will never be resolved.

An attempt to fix this [1] turned out to be not sufficient. For now revert
load_unaligned_zeropad() until this problem has been resolved in a proper
way.

Note that the implementation of load_unaligned_zeropad() itself is
correct. The revert is just a temporary workaround until there is complete
fix for secure storage access exceptions.

[1] commit b00be77302 ("s390/mm: Add missing secure storage access fixups for donated memory")

Fixes: 802ba53eef ("s390: add support for DCACHE_WORD_ACCESS")
Cc: stable@vger.kernel.org
Acked-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
2026-06-12 11:30:25 +02:00

44 lines
962 B
C

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_WORD_AT_A_TIME_H
#define _ASM_WORD_AT_A_TIME_H
#include <linux/bitops.h>
#include <linux/wordpart.h>
#include <asm/bitsperlong.h>
struct word_at_a_time {
const unsigned long bits;
};
#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x7f) }
static inline unsigned long prep_zero_mask(unsigned long val, unsigned long data, const struct word_at_a_time *c)
{
return data;
}
static inline unsigned long create_zero_mask(unsigned long data)
{
return __fls(data);
}
static inline unsigned long find_zero(unsigned long data)
{
return (data ^ (BITS_PER_LONG - 1)) >> 3;
}
static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c)
{
unsigned long mask = (val & c->bits) + c->bits;
*data = ~(mask | val | c->bits);
return *data;
}
static inline unsigned long zero_bytemask(unsigned long data)
{
return ~1UL << data;
}
#endif /* _ASM_WORD_AT_A_TIME_H */