mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 03:35:32 -04:00
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] commitb00be77302("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>
44 lines
962 B
C
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 */
|